Skip to content
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
fc6bcd2
AI-1343 feat: add links for data apps
mariankrotil Aug 15, 2025
56b8805
AI-1343 style: apply flake8 changes
mariankrotil Aug 15, 2025
69e0605
AI-1343 feat: update workspace add method for getting workspace id fo…
mariankrotil Aug 15, 2025
2259abf
AI-1343 feat: add data app tools for creating, updating, deploying, s…
mariankrotil Aug 15, 2025
5593368
AI-1343 feat: init tools to the mcp server
mariankrotil Aug 15, 2025
aa342ef
AI-1343 feat: update mcp server with data tools; and update tools doc md
mariankrotil Aug 15, 2025
a5ca7c8
AI-1343 fix: add # to the storage_api_token secrets for data app in o…
mariankrotil Aug 15, 2025
f5df100
AI-1343 fix: update authorization checker and code injection
mariankrotil Aug 15, 2025
ce67f45
Merge AI-1343-cleint methods to AI-1343-tools
mariankrotil Aug 18, 2025
152b68b
Merge branch 'AI-1343-mcp-add-support-for-data-apps' into AI-1343-mcp…
mariankrotil Aug 18, 2025
27bf4d8
AI-1343 feat: improve secrets encryption in the tool and in the data …
mariankrotil Aug 18, 2025
a0b4e73
AI-1343 test: align test wrt changes
mariankrotil Aug 18, 2025
c57dfb0
AI-1343 docs: update tools md
mariankrotil Aug 18, 2025
f0d892e
Merge branch 'AI-1343-mcp-add-support-for-data-apps' into AI-1343-mcp…
mariankrotil Aug 18, 2025
780082d
AI-1343 refactor: update code wrt changes
mariankrotil Aug 18, 2025
63c8da1
AI-1343 chore: update vers and add cryptography dep
mariankrotil Aug 18, 2025
b369b48
Merge branch 'AI-1343-mcp-add-support-for-data-apps' into AI-1343-mcp…
mariankrotil Aug 18, 2025
6845ef9
AI-1343 fix: update pyproject
mariankrotil Aug 18, 2025
a671bc9
AI-1343 refactor: unify get_data_apps output
mariankrotil Aug 19, 2025
87ee479
AI-1343 fix: remove format from source code as causing errors when us…
mariankrotil Aug 19, 2025
ca66b06
AI-1343 feat: add metadata created by mcp to the data apps
mariankrotil Aug 19, 2025
862a631
AI-1343 style: apply flake8 changes
mariankrotil Aug 19, 2025
f17c63a
AI-1343 docs: update tools.md documentation wrt recent changes
mariankrotil Aug 19, 2025
4fe4822
AI-1343 perf(docs): improve docs of create data app wrt agent testing…
mariankrotil Aug 19, 2025
67f83f5
AI-1343 docs: update tool.md file wrt new changes
mariankrotil Aug 19, 2025
b41cf5d
AI-1343 style: apply flake8 changes
mariankrotil Aug 19, 2025
23f9ca8
Merge AI-1343-clients to AI-1343-data-apps
mariankrotil Aug 19, 2025
e6fa054
AI-1343 docs: update tools md
mariankrotil Aug 19, 2025
a6fe578
AI-1343 refactor: update data apps wrt client changes
mariankrotil Aug 19, 2025
9f27682
Merge branch 'AI-1343-mcp-add-support-for-data-apps' into AI-1343-mcp…
mariankrotil Aug 20, 2025
f271acd
AI-1343 refactor: clean data apps code, simplify
mariankrotil Aug 20, 2025
005c2aa
AI-1343 revert: using dict.get method to retrieve info about workspac…
mariankrotil Aug 20, 2025
6dd5864
AI-1343 refactor: update code wrt reviews, rename sync to modify, upd…
mariankrotil Aug 20, 2025
0961f14
AI-1343 refactor: simplify password links
mariankrotil Aug 20, 2025
565de6f
AI-1343 test: update tools.md and update tests
mariankrotil Aug 20, 2025
6bcf6e1
AI-1343 refactor: simplify code, remove annotations from tool return …
mariankrotil Aug 20, 2025
126a953
AI-1343 docs: update tools md wrt changes
mariankrotil Aug 20, 2025
319a59e
Merge main into AI-1343-tools
mariankrotil Aug 20, 2025
c576cf0
AI-1343 fix: swap position of building secrets in data app
mariankrotil Aug 20, 2025
86c4feb
AI-1343 refactor(git status): improve code, simplify classes, make pa…
mariankrotil Aug 21, 2025
10ff00c
AI-1343 test: update tests wrt changes, add tests for safe types
mariankrotil Aug 21, 2025
c349c7e
AI-1343 docs: update tools md wrt new desc in data apps
mariankrotil Aug 21, 2025
685510d
AI-1343 refactor: add error hanlding for missing configuration ids
mariankrotil Aug 21, 2025
6795d9d
Merge branch 'main' into AI-1343-mcp-add-support-for-data-apps-tool
Aug 21, 2025
f8398df
AI-1343: improve 'packages' field description
Aug 21, 2025
152fccc
AI-1343: re-run the global search in the test
Aug 21, 2025
49c8064
AI-1406: skip test_global_search_end_to_end() integration test
Aug 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions TOOLS.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ filtering.
### OAuth Tools
- [create_oauth_url](#create_oauth_url): Generates an OAuth authorization URL for a Keboola component configuration.

### Other Tools
- [get_data_apps](#get_data_apps): Lists summaries of data apps in the project given the limit and offset or gets details of a data apps by
providing its configuration IDs.
- [manage_data_app](#manage_data_app): Deploys a data app or stops running data app in the Keboola workspace integration given the action and config
id.
- [modify_data_app](#modify_data_app): Creates or updates a Streamlit data app in Keboola workspace integration.

### Project Tools
- [get_project_info](#get_project_info): Return structured project information pulled from multiple endpoints.

Expand Down Expand Up @@ -869,6 +876,168 @@ EXAMPLES:

---

# Other Tools
<a name="get_data_apps"></a>
## get_data_apps
**Annotations**: `read-only`

**Tags**: `data-app`

**Description**:

Lists summaries of data apps in the project given the limit and offset or gets details of a data apps by
providing its configuration IDs.

Considerations:
- If configuration_ids are provided, the tool will return details of the data apps by their configuration IDs.
- If no configuration_ids are provided, the tool will list all data apps in the project given the limit and offset.
- Data App details contain configurations, deployment info along with logs and links to the data app dashboard.


**Input JSON Schema**:
```json
{
"properties": {
"configuration_ids": {
"default": [],
"description": "The IDs of the data app configurations.",
"items": {
"type": "string"
},
"title": "Configuration Ids",
"type": "array"
},
"limit": {
"default": 100,
"description": "The limit of the data apps to fetch.",
"title": "Limit",
"type": "integer"
},
"offset": {
"default": 0,
"description": "The offset of the data apps to fetch.",
"title": "Offset",
"type": "integer"
}
},
"type": "object"
}
```

---
<a name="manage_data_app"></a>
## manage_data_app
**Annotations**:

**Tags**: `data-app`

**Description**:

Deploys a data app or stops running data app in the Keboola workspace integration given the action and config
id.


**Input JSON Schema**:
```json
{
"properties": {
"action": {
"description": "The action to perform.",
"enum": [
"deploy",
"stop"
],
"title": "Action",
"type": "string"
},
"configuration_id": {
"description": "The ID of the data app configuration.",
"title": "Configuration Id",
"type": "string"
}
},
"required": [
"action",
"configuration_id"
],
"type": "object"
}
```

---
<a name="modify_data_app"></a>
## modify_data_app
**Annotations**: `destructive`

**Tags**: `data-app`

**Description**:

Creates or updates a Streamlit data app in Keboola workspace integration.

Considerations:
- The `source_code` parameter must be a complete and runnable Streamlit app. It must include a placeholder
`{QUERY_DATA_FUNCTION}` where a `query_data` function will be injected. This function accepts a string of SQL
query following current sql dialect and returns a pandas DataFrame with the results from the workspace.
- Write SQL queries so they are compatible with the current workspace backend, you can ensure this by using the
`query_data` tool to inspect the data in the workspace before using it in the data app.
- If you're updating an existing data app, provide the `configuration_id` parameter. In this case, all existing
parameters must either be preserved or explicitly updated. If the data app is deployed, it needs to be redeployed
to apply the changes.


**Input JSON Schema**:
```json
{
"properties": {
"name": {
"description": "Name of the data app.",
"title": "Name",
"type": "string"
},
"description": {
"description": "Description of the data app.",
"title": "Description",
"type": "string"
},
"source_code": {
"description": "Complete Python/Streamlit source code for the data app.",
"title": "Source Code",
"type": "string"
},
"packages": {
"description": "Python packages used in the source code necessary to be installed.",
"items": {
"type": "string"
},
"title": "Packages",
"type": "array"
},
"authorization_required": {
"default": false,
"description": "Whether the data app is authorized using simple password or not.",
"title": "Authorization Required",
"type": "boolean"
},
"configuration_id": {
"default": "",
"description": "The ID of existing data app configuration when updating, otherwise empty string.",
"title": "Configuration Id",
"type": "string"
}
},
"required": [
"name",
"description",
"source_code",
"packages"
],
"type": "object"
}
```

---

# Documentation Tools
<a name="docs_query"></a>
## docs_query
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "keboola-mcp-server"
version = "1.18.1"
version = "1.19.0"
description = "MCP server for interacting with Keboola Connection"
readme = "README.md"
requires-python = ">=3.10"
Expand All @@ -17,6 +17,7 @@ dependencies = [
"jsonschema ~= 4.23",
"pyjwt ~= 2.10",
"json-log-formatter ~= 1.0",
"cryptography ~= 45.0",
]
[project.optional-dependencies]
codestyle = [
Expand Down
40 changes: 39 additions & 1 deletion src/keboola_mcp_server/links.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

from pydantic import BaseModel, ConfigDict, Field

from keboola_mcp_server.clients.client import CONDITIONAL_FLOW_COMPONENT_ID, FlowType, KeboolaClient
from keboola_mcp_server.clients.client import (
CONDITIONAL_FLOW_COMPONENT_ID,
FlowType,
KeboolaClient,
)

URLType = Literal['ui-detail', 'ui-dashboard', 'docs']

Expand Down Expand Up @@ -95,6 +99,40 @@ def get_configuration_links(self, component_id: str, configuration_id: str, conf
self.get_config_dashboard_link(component_id=component_id, component_name=component_id),
]

# --- Data Apps ---
def get_data_app_config_link(self, configuration_id: str, configuration_name: str, is_authorized: bool) -> Link:
title = (
f'Data App Configuration (To see password, click on "OPEN DATA APP"): {configuration_name}'
if is_authorized
else f'Data App Configuration: {configuration_name}'
)
return Link.detail(title=title, url=self._url(f'data-apps/{configuration_id}'))

def get_data_app_dashboard_link(self) -> Link:
return Link.dashboard(title='Data Apps in the project', url=self._url('data-apps'))

def get_data_app_deployment_link(self, deployment_link: str) -> Link:
return Link.detail(title='Data App Deployment', url=deployment_link)

def get_data_app_links(
self,
configuration_id: str,
configuration_name: str,
deployment_link: str | None = None,
is_authorized: bool = False,
) -> list[Link]:
links = [
self.get_data_app_config_link(
configuration_id=configuration_id,
configuration_name=configuration_name,
is_authorized=is_authorized,
),
self.get_data_app_dashboard_link(),
]
if deployment_link:
links.append(self.get_data_app_deployment_link(deployment_link))
return links

# --- Transformations ---
def get_transformations_dashboard_link(self) -> Link:
return Link.dashboard(title='Transformations dashboard', url=self._url('transformations-v2'))
Expand Down
2 changes: 2 additions & 0 deletions src/keboola_mcp_server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from keboola_mcp_server.oauth import SimpleOAuthProvider
from keboola_mcp_server.prompts.add_prompts import add_keboola_prompts
from keboola_mcp_server.tools.components import add_component_tools
from keboola_mcp_server.tools.data_apps import add_data_app_tools
from keboola_mcp_server.tools.doc import add_doc_tools
from keboola_mcp_server.tools.flow.tools import add_flow_tools
from keboola_mcp_server.tools.jobs import add_job_tools
Expand Down Expand Up @@ -215,6 +216,7 @@ def create_server(
custom_routes.add_to_mcp(mcp)

add_component_tools(mcp)
add_data_app_tools(mcp)
add_doc_tools(mcp)
add_flow_tools(mcp)
add_job_tools(mcp)
Expand Down
Loading