Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 11 additions & 11 deletions modelcontextprotocol/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ Open `Cursor > Settings > Tools & Integrations > New MCP Server` to include the
| Tool | Description |
| ------------------- | ----------------------------------------------------------------- |
| `search_assets` | Search for assets based on conditions |
| `get_assets_by_dsl` | Retrieve assets using a DSL query |
| `traverse_lineage` | Retrieve lineage for an asset |
| `get_assets_dsl` | Retrieve assets using a DSL query |
| `get_lineage` | Retrieve lineage for an asset |
| `update_assets` | Update asset attributes (user description and certificate status) |
| `create_glossaries` | Create glossaries |
| `create_glossary_categories` | Create glossary categories |
Expand Down Expand Up @@ -173,7 +173,7 @@ You can restrict access to specific tools using the `RESTRICTED_TOOLS` environme
"-e",
"ATLAN_AGENT_ID=<YOUR_AGENT_ID>",
"-e",
"RESTRICTED_TOOLS=get_assets_by_dsl_tool,update_assets_tool",
"RESTRICTED_TOOLS=get_assets_dsl,update_assets",
"ghcr.io/atlanhq/atlan-mcp-server:latest"
]
}
Expand All @@ -193,7 +193,7 @@ You can restrict access to specific tools using the `RESTRICTED_TOOLS` environme
"ATLAN_API_KEY": "<YOUR_API_KEY>",
"ATLAN_BASE_URL": "https://<YOUR_INSTANCE>.atlan.com",
"ATLAN_AGENT_ID": "<YOUR_AGENT_ID>",
"RESTRICTED_TOOLS": "get_assets_by_dsl_tool,update_assets_tool"
"RESTRICTED_TOOLS": "get_assets_dsl,update_assets"
}
}
}
Expand All @@ -204,10 +204,10 @@ You can restrict access to specific tools using the `RESTRICTED_TOOLS` environme

You can restrict any of the following tools:

- `search_assets_tool` - Asset search functionality
- `get_assets_by_dsl_tool` - DSL query execution
- `traverse_lineage_tool` - Lineage traversal
- `update_assets_tool` - Asset updates (descriptions, certificates)
- `search_assets` - Asset search functionality
- `get_assets_dsl` - DSL query execution
- `get_lineage` - Lineage traversal
- `update_assets` - Asset updates (descriptions, certificates)
- `create_glossaries` - Glossary creation
- `create_glossary_categories` - Category creation
- `create_glossary_terms` - Term creation
Expand All @@ -217,19 +217,19 @@ You can restrict any of the following tools:
#### Read-Only Access
Restrict all write operations:
```
RESTRICTED_TOOLS=update_assets_tool,create_glossaries,create_glossary_categories,create_glossary_terms
RESTRICTED_TOOLS=update_assets,create_glossaries,create_glossary_categories,create_glossary_terms
```

#### Disable DSL Queries
For security or performance reasons:
```
RESTRICTED_TOOLS=get_assets_by_dsl_tool
RESTRICTED_TOOLS=get_assets_dsl
```

#### Minimal Access
Allow only basic search:
```
RESTRICTED_TOOLS=get_assets_by_dsl_tool,update_assets_tool,traverse_lineage_tool,create_glossaries,create_glossary_categories,create_glossary_terms
RESTRICTED_TOOLS=get_assets_dsl,update_assets,get_lineage,create_glossaries,create_glossary_categories,create_glossary_terms
```

### How It Works
Expand Down
57 changes: 32 additions & 25 deletions modelcontextprotocol/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
from typing import Any, Dict, List
from fastmcp import FastMCP
from tools import (
search_assets,
search_assets as search,
get_assets_by_dsl,
traverse_lineage,
update_assets,
update_assets as update,
create_glossary_category_assets,
create_glossary_assets,
create_glossary_term_assets,
Expand All @@ -21,6 +21,8 @@
parse_list_parameter,
)
from middleware import ToolRestrictionMiddleware
from starlette.requests import Request
from starlette.responses import PlainTextResponse


mcp = FastMCP("Atlan MCP Server", dependencies=["pyatlan", "fastmcp"])
Expand All @@ -39,8 +41,13 @@
mcp.add_middleware(tool_restriction)


@mcp.custom_route("/health", methods=["GET"])
async def health_check(request: Request) -> PlainTextResponse:
return PlainTextResponse("OK")


@mcp.tool()
def search_assets_tool(
def search_assets(
conditions=None,
negative_conditions=None,
some_conditions=None,
Expand Down Expand Up @@ -95,13 +102,13 @@ def search_assets_tool(

Examples:
# Search for verified tables
tables = search_assets(
tables = search(
asset_type="Table",
conditions={"certificate_status": CertificateStatus.VERIFIED.value}
)

# Search for assets missing descriptions from the database/connection default/snowflake/123456/abc
missing_desc = search_assets(
missing_desc = search(
connection_qualified_name="default/snowflake/123456/abc",
negative_conditions={
"description": "has_any_value",
Expand All @@ -111,7 +118,7 @@ def search_assets_tool(
)

# Search for columns with specific certificate status
columns = search_assets(
columns = search(
asset_type="Column",
some_conditions={
"certificate_status": [CertificateStatus.DRAFT.value, CertificateStatus.VERIFIED.value]
Expand All @@ -121,7 +128,7 @@ def search_assets_tool(
date_range={"create_time": {"gte": 1641034800000, "lte": 1672570800000}}
)
# Search for assets with a specific search text
assets = search_assets(
assets = search(
conditions = {
"name": {
"operator": "match",
Expand All @@ -136,7 +143,7 @@ def search_assets_tool(


# Search for assets using advanced operators
assets = search_assets(
assets = search(
conditions={
"name": {
"operator": "startswith",
Expand All @@ -156,31 +163,31 @@ def search_assets_tool(
)

# For multiple asset types queries. ex: Search for Table, Column, or View assets from the database/connection default/snowflake/123456/abc
assets = search_assets(
assets = search(
connection_qualified_name="default/snowflake/123456/abc",
conditions={
"type_name": ["Table", "Column", "View"],
}
)

# Search for assets with compliant business policy
assets = search_assets(
assets = search(
conditions={
"asset_policy_guids": "business_policy_guid"
},
include_attributes=["asset_policy_guids"]
)

# Search for assets with non compliant business policy
assets = search_assets(
assets = search(
conditions={
"non_compliant_asset_policy_guids": "business_policy_guid"
},
include_attributes=["non_compliant_asset_policy_guids"]
)

# get non compliant business policies for an asset
assets = search_assets(
assets = search(
conditions={
"name": "has_any_value",
"displayName": "has_any_value",
Expand All @@ -190,7 +197,7 @@ def search_assets_tool(
)

# get compliant business policies for an asset
assets = search_assets(
assets = search(
conditions={
"name": "has_any_value",
"displayName": "has_any_value",
Expand All @@ -200,7 +207,7 @@ def search_assets_tool(
)

# get incident for a business policy
assets = search_assets(
assets = search(
conditions={
"asset_type": "BusinessPolicyIncident",
"business_policy_incident_related_policy_guids": "business_policy_guid"
Expand All @@ -211,7 +218,7 @@ def search_assets_tool(
)

# Search for glossary terms by name and status
glossary_terms = search_assets(
glossary_terms = search(
asset_type="AtlasGlossaryTerm",
conditions={
"certificate_status": CertificateStatus.VERIFIED.value,
Expand Down Expand Up @@ -242,7 +249,7 @@ def search_assets_tool(
domain_guids = parse_list_parameter(domain_guids)
guids = parse_list_parameter(guids)

return search_assets(
return search(
conditions,
negative_conditions,
some_conditions,
Expand All @@ -266,7 +273,7 @@ def search_assets_tool(


@mcp.tool()
def get_assets_by_dsl_tool(dsl_query):
def get_assets_dsl(dsl_query):
"""
Execute the search with the given query
dsl_query : Union[str, Dict[str, Any]] (required):
Expand Down Expand Up @@ -338,7 +345,7 @@ def get_assets_by_dsl_tool(dsl_query):


@mcp.tool()
def traverse_lineage_tool(
def get_lineage(
guid,
direction,
depth=1000000,
Expand Down Expand Up @@ -374,7 +381,7 @@ def traverse_lineage_tool(

Examples:
# Get lineage with default attributes
lineage = traverse_lineage_tool(
lineage = traverse_lineage(
guid="asset-guid-here",
direction="DOWNSTREAM",
depth=1000,
Expand Down Expand Up @@ -402,7 +409,7 @@ def traverse_lineage_tool(


@mcp.tool()
def update_assets_tool(
def update_assets(
assets,
attribute_name,
attribute_values,
Expand All @@ -426,7 +433,7 @@ def update_assets_tool(

Examples:
# Update certificate status for a single asset
result = update_assets_tool(
result = update(
assets={
"guid": "asset-guid-here",
"name": "Asset Name",
Expand All @@ -438,7 +445,7 @@ def update_assets_tool(
)

# Update user description for multiple assets
result = update_assets_tool(
result = update(
assets=[
{
"guid": "asset-guid-1",
Expand All @@ -460,7 +467,7 @@ def update_assets_tool(
)

# Update readme for a single asset with Markdown
result = update_assets_tool(
result = update(
assets={
"guid": "asset-guid-here",
"name": "Asset Name",
Expand Down Expand Up @@ -496,7 +503,7 @@ def update_assets_tool(
else:
updatable_assets = [UpdatableAsset(**asset) for asset in parsed_assets]

return update_assets(
return update(
updatable_assets=updatable_assets,
attribute_name=attr_enum,
attribute_values=parsed_attribute_values,
Expand Down Expand Up @@ -714,7 +721,7 @@ def main():
"--port", type=int, default=8000, help="Port to run the server on"
)
parser.add_argument(
"--path", type=str, default="/", help="Path of the streamable HTTP server"
"--path", type=str, default="/mcp/", help="Path of the streamable HTTP server"
)
args = parser.parse_args()

Expand Down