Skip to content

Commit 0f07586

Browse files
authored
Moving from fastmcp to mcp, using uv for setup (#3)
* fix: moving from fastmcp to mcp, using uv for setup * chore: uv.lock * fix: uv installation in ci * fix: uv for pre-commit checks
1 parent 41bb360 commit 0f07586

File tree

10 files changed

+647
-1248
lines changed

10 files changed

+647
-1248
lines changed

.github/workflows/checks.yml

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,18 @@ jobs:
1717
steps:
1818
- uses: actions/checkout@v4
1919
#----------------------------------------------
20-
# ----- install & configure poetry -----
20+
# ----- install & configure Python + UV -----
2121
#----------------------------------------------
22-
- name: Install Poetry
23-
uses: snok/install-poetry@v1
24-
with:
25-
version: 1.8.5
26-
virtualenvs-create: true
27-
virtualenvs-in-project: true
28-
virtualenvs-path: .venv
29-
installer-parallel: true
3022
- uses: actions/setup-python@v5
3123
with:
3224
python-version: '3.11'
33-
- name: Install dependencies
25+
- name: Install UV
26+
uses: astral-sh/setup-uv@v5
27+
#----------------------------------------------
28+
# ----- install dependencies & run pre-commit -----
29+
#----------------------------------------------
30+
- name: Install dependencies and run pre-commit
3431
run: |
35-
poetry config virtualenvs.in-project true
36-
poetry install
37-
- uses: pre-commit/[email protected]
32+
uv pip install --system pre-commit
33+
# Run pre-commit directly
34+
pre-commit run --all-files

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,3 @@ cython_debug/
158158
# and can be added to the global gitignore or merged into this file. For a more nuclear
159159
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
160160
#.idea/
161-
162-
# this is generated by uv when installing deps by fastmcp server
163-
uv.lock

modelcontextprotocol/.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.11

modelcontextprotocol/client.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import logging
44

55
from pyatlan.client.atlan import AtlanClient
6-
76
from settings import Settings
87

98
logger = logging.getLogger(__name__)

modelcontextprotocol/pyproject.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[project]
2+
name = "atlan-mcp"
3+
version = "0.1.0"
4+
description = "Atlan Model Context Protocol server for interacting with Atlan services"
5+
readme = "README.md"
6+
requires-python = ">=3.11"
7+
dependencies = [
8+
"mcp[cli]>=1.6.0",
9+
"pyatlan>=6.0.1",
10+
]

modelcontextprotocol/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from fastmcp import FastMCP
1+
from mcp.server.fastmcp import FastMCP
22
from tools import search_assets, get_assets_by_dsl
33
from pyatlan.model.fields.atlan_fields import AtlanField
44
from typing import Optional, Dict, Any, List, Union, Type

modelcontextprotocol/tools.py

Lines changed: 5 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -68,33 +68,6 @@ def search_assets(
6868
6969
Raises:
7070
Exception: If there's an error executing the search
71-
72-
Examples:
73-
# Search for verified tables
74-
tables = search_assets(
75-
asset_type="Table",
76-
conditions={"certificate_status": CertificateStatus.VERIFIED.value}
77-
)
78-
79-
# Search for assets missing descriptions
80-
missing_desc = search_assets(
81-
negative_conditions={
82-
"description": "has_any_value",
83-
"user_description": "has_any_value"
84-
},
85-
include_attributes=["owner_users", "owner_groups"]
86-
)
87-
88-
# Search for columns with specific certificate status
89-
columns = search_assets(
90-
asset_type="Column",
91-
some_conditions={
92-
"certificate_status": [CertificateStatus.DRAFT.value, CertificateStatus.VERIFIED.value]
93-
},
94-
tags=["PRD"],
95-
conditions={"created_by": "username"},
96-
date_range={"create_time": {"gte": 1641034800000, "lte": 1672570800000}}
97-
)
9871
"""
9972
logger.info(
10073
f"Starting asset search with parameters: asset_type={asset_type}, "
@@ -414,79 +387,14 @@ def search_assets(
414387
def get_assets_by_dsl(dsl_query: str) -> Dict[str, Any]:
415388
"""
416389
Execute the search with the given query
417-
dsl_query (required):
418-
The DSL object that is required to search the index.
419-
420-
Example:
421-
dsl_query = '''{
422-
"query": {
423-
"function_score": {
424-
"boost_mode": "sum",
425-
"functions": [
426-
{"filter": {"match": {"starredBy": "john.doe"}}, "weight": 10},
427-
{"filter": {"match": {"certificateStatus": "VERIFIED"}}, "weight": 15},
428-
{"filter": {"match": {"certificateStatus": "DRAFT"}}, "weight": 10},
429-
{"filter": {"bool": {"must_not": [{"exists": {"field": "certificateStatus"}}]}}, "weight": 8},
430-
{"filter": {"bool": {"must_not": [{"terms": {"__typeName.keyword": ["Process", "DbtProcess"]}}]}}, "weight": 20}
431-
],
432-
"query": {
433-
"bool": {
434-
"filter": [
435-
{
436-
"bool": {
437-
"minimum_should_match": 1,
438-
"must": [
439-
{"bool": {"should": [{"terms": {"certificateStatus": ["VERIFIED"]}}]}},
440-
{"term": {"__state": "ACTIVE"}}
441-
],
442-
"must_not": [
443-
{"term": {"isPartial": "true"}},
444-
{"terms": {"__typeName.keyword": ["Procedure", "DbtColumnProcess", "BIProcess", "MatillionComponent", "SnowflakeTag", "DbtTag", "BigqueryTag", "AIApplication", "AIModel"]}},
445-
{"terms": {"__typeName.keyword": ["MCIncident", "AnomaloCheck"]}}
446-
],
447-
"should": [
448-
{"terms": {"__typeName.keyword": ["Query", "Collection", "AtlasGlossary", "AtlasGlossaryCategory", "AtlasGlossaryTerm", "Connection", "File"]}},
449-
]
450-
}
451-
}
452-
]
453-
},
454-
"score_mode": "sum"
455-
},
456-
"score_mode": "sum"
457-
}
458-
},
459-
"post_filter": {
460-
"bool": {
461-
"filter": [
462-
{
463-
"bool": {
464-
"must": [{"terms": {"__typeName.keyword": ["Table", "Column"]}}],
465-
"must_not": [{"exists": {"field": "termType"}}]
466-
}
467-
}
468-
]
469-
},
470-
"sort": [
471-
{"_score": {"order": "desc"}},
472-
{"popularityScore": {"order": "desc"}},
473-
{"starredCount": {"order": "desc"}},
474-
{"name.keyword": {"order": "asc"}}
475-
],
476-
"track_total_hits": true,
477-
"size": 10,
478-
"include_meta": false
479-
}'''
480-
dsl_query = json.loads(dsl_query)
481-
response = get_assets_by_dsl(dsl_query)
482-
390+
Args:
391+
dsl_query (required): The DSL object that is required to search the index.
392+
Returns:
393+
Dict[str, Any]: A dictionary containing the results and aggregations
483394
"""
484395
logger.info("Starting DSL-based asset search")
485396
if logger.isEnabledFor(logging.DEBUG):
486-
if isinstance(dsl_query, str):
487-
# Only log a portion of the DSL string if it's too large
488-
log_query = dsl_query[:500] + "..." if len(dsl_query) > 500 else dsl_query
489-
logger.debug(f"DSL query string: {log_query}")
397+
logger.debug("Processing DSL query string")
490398
try:
491399
# Parse string to dict if needed
492400
if isinstance(dsl_query, str):

0 commit comments

Comments
 (0)