LangChain toolkit for Microsoft Fabric OneLake — workspace, file, table, directory, and item operations powered by the Fabric MCP Server.
Project description
langchain-onelake
LangChain toolkit for Microsoft Fabric OneLake — powered by the Fabric MCP Server.
Connect your LangChain / LangGraph agents to OneLake with zero boilerplate. This toolkit dynamically loads all OneLake tools from the Fabric MCP Server (fabmcp) and presents them as LangChain-compatible tools.
Features
- Context-aware tools — set workspace + item once, all subsequent calls auto-inject context
- Raw MCP tools — full pass-through for power users who want direct control
- OneLake tools across 8 categories — workspace, item, file, directory, upload/download, blob, and table
- Local & remote — connect to a local
fabmcpbinary (stdio) or a remote server (HTTP/SSE) - Auto-discovery — tools stay in sync with the Fabric MCP Server
- Category filtering — load all tools or just the ones you need
- Async context manager — clean startup and shutdown of the MCP server
- Flexible auth — uses your Azure CLI / managed identity credentials (local), or bearer tokens (remote)
- Model-agnostic — works with OpenAI, Azure AI Foundry (OpenAI, Llama, Mistral, Phi, etc.), Anthropic, Google, Ollama, or any LangChain-supported model
Installation
pip install langchain-onelake
Prerequisites
- Fabric MCP Server (
fabmcp) — build from source or install the binary - Azure authentication — run
az loginor configure managed identity - Python 3.10+
Quick Start — Context-Aware Tools (Recommended)
Context-aware tools let the agent set a workspace and item once — all subsequent operations automatically use that context:
import asyncio
from langchain_onelake import OneLakeToolkit
async def main():
async with OneLakeToolkit.create("path/to/fabmcp") as toolkit:
# Context-aware tools — agent sets context once, then queries flow naturally
tools = toolkit.get_context_tools()
print(f"Loaded {len(tools)} context-aware tools:")
for t in tools:
print(f" - {t.name}: {t.description[:80]}")
asyncio.run(main())
Context-Aware Tool List
| Tool | Description |
|---|---|
set_onelake_context |
Set the active workspace and item (by name, ID, or URI) |
get_onelake_context |
Check the currently set workspace and item context |
list_onelake_workspaces |
List all workspaces available to the current user |
list_onelake_items |
List items (lakehouses, warehouses, …) in the active workspace |
list_onelake_items_data |
List items via DFS data API |
create_onelake_item |
Create a new Fabric item (Lakehouse, Notebook, etc.) |
list_onelake_tables |
List tables (Delta/Iceberg) in the active item |
list_onelake_folders |
List folders/directories at a given path |
get_onelake_table_metadata |
Get file-level metadata for a table |
read_onelake_file |
Read file content from the active item |
write_onelake_file |
Write content to a file in OneLake |
delete_onelake_file |
Delete a file from OneLake |
upload_onelake_file |
Upload content to OneLake storage |
download_onelake_file |
Download a file with metadata |
create_onelake_directory |
Create a directory (supports nested structures) |
delete_onelake_directory |
Delete a directory |
list_onelake_blobs |
List files and directories as blobs |
delete_onelake_blob |
Delete a blob |
list_onelake_tables_api |
List tables via Iceberg REST catalog |
get_onelake_table_api |
Get detailed table metadata (columns, types, stats) |
get_onelake_table_config |
Get table endpoint configuration |
list_onelake_namespaces |
List table namespaces/schemas |
get_onelake_namespace |
Get namespace metadata |
How Context Works
User: "What tables are in the Sales lakehouse in the Marketing workspace?"
↓
Agent calls: set_onelake_context(workspace="Marketing", item="Sales")
↓ Context stored: workspace=Marketing, item=Sales (Lakehouse)
Agent calls: list_onelake_tables() ← no IDs needed!
↓ Context auto-injected
Agent returns: table list
Quick Start — Raw Tools (Advanced)
For full control over every MCP parameter:
import asyncio
from langchain_onelake import OneLakeToolkit
async def main():
async with OneLakeToolkit.create("path/to/fabmcp") as toolkit:
# Raw MCP tools — pass workspace/item on every call
tools = toolkit.get_tools()
print(f"Loaded {len(tools)} raw tools:")
for t in tools:
print(f" - {t.name}: {t.description[:80]}")
asyncio.run(main())
Remote server (HTTP/SSE)
import asyncio
from langchain_onelake import OneLakeToolkit
async def main():
# Connect to a remotely hosted Fabric MCP Server
async with OneLakeToolkit.from_url("https://fabmcp.example.com/sse") as toolkit:
tools = toolkit.get_context_tools()
print(f"Loaded {len(tools)} tools")
# With authentication
async with OneLakeToolkit.from_url(
"https://fabmcp.example.com/sse",
headers={"Authorization": "Bearer <your-token>"},
) as toolkit:
tools = toolkit.get_context_tools()
asyncio.run(main())
Usage with LangGraph Agent
Works with any model provider — OpenAI, Azure OpenAI, Anthropic, Google, Ollama, etc.:
import asyncio
from langchain_onelake import OneLakeToolkit
from langchain.chat_models import init_chat_model
from langgraph.graph import StateGraph, MessagesState, START
from langgraph.prebuilt import ToolNode, tools_condition
SYSTEM_PROMPT = """You are a data assistant connected to Microsoft Fabric OneLake.
WORKFLOW:
1. If the user mentions a workspace or item, call set_onelake_context first.
2. Once context is set, list tables, browse files, inspect metadata, etc.
3. If no context is set, list workspaces to help the user pick one.
Present tabular data in clean markdown tables. Be concise."""
async def main():
async with OneLakeToolkit.create() as toolkit:
tools = toolkit.get_context_tools()
# Use any model — just change the model name
model = init_chat_model("gpt-4o", temperature=0)
def call_model(state: MessagesState):
messages = [{"role": "system", "content": SYSTEM_PROMPT}] + state["messages"]
return {"messages": model.bind_tools(tools).invoke(messages)}
builder = StateGraph(MessagesState)
builder.add_node("agent", call_model)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "agent")
builder.add_conditional_edges("agent", tools_condition)
builder.add_edge("tools", "agent")
agent = builder.compile()
# Run a query
result = await agent.ainvoke(
{"messages": [{"role": "user", "content": "List my OneLake workspaces"}]}
)
print(result["messages"][-1].content)
asyncio.run(main())
Accessing the Context Object
You can read or modify the context programmatically:
async with OneLakeToolkit.create() as toolkit:
tools = toolkit.get_context_tools()
# Pre-set context before the agent runs
toolkit.context.workspace_id = "12345678-..."
toolkit.context.workspace_name = "Marketing"
toolkit.context.item_id = "87654321-..."
toolkit.context.item_name = "SalesLH"
toolkit.context.item_type = "Lakehouse"
# Now the agent can query without calling set_onelake_context
print(toolkit.context.summary())
# → "workspace=Marketing, item=SalesLH (Lakehouse)"
Raw Tool Categories
Filter raw tools by category when you only need a subset:
async with OneLakeToolkit.create() as toolkit:
# Only table tools
table_tools = toolkit.get_tools(category="table")
# Only file operations
file_tools = toolkit.get_tools(category="file")
# List all categories
print(toolkit.categories)
| Category | Tools | Description |
|---|---|---|
workspace |
workspace_list |
List OneLake workspaces |
item |
item_list, item_list-data, item_create |
List and create Fabric items |
file |
file_list, file_read, file_write, file_delete |
Read/write files in OneLake |
directory |
directory_create, directory_delete |
Manage directories |
upload |
upload_file |
Upload files via blob API |
download |
download_file |
Download files from OneLake |
blob |
blob_list, blob_delete |
Blob storage operations |
table |
table_config_get, table_list, table_get, ... |
Table introspection (schemas, columns, stats) |
Configuration
Environment Variables
| Variable | Description | Default |
|---|---|---|
FABMCP_PATH |
Path to fabmcp executable (local mode) |
Searches $PATH |
FABMCP_URL |
URL of remote Fabric MCP Server (remote mode) | None |
ONELAKE_ENVIRONMENT |
OneLake environment (default: PROD) |
None |
Programmatic Configuration
Local (stdio):
toolkit = await OneLakeToolkit.create(
command=r"C:\fabmcp.exe", # Explicit path
environment="PROD", # Override OneLake environment
namespaces=["onelake"], # Restrict to specific namespaces
env={"CUSTOM_VAR": "value"}, # Extra env vars for the server
)
Remote (HTTP/SSE):
toolkit = await OneLakeToolkit.from_url(
"https://fabmcp.example.com/sse",
headers={"Authorization": "Bearer <token>"},
)
API Reference
OneLakeToolkit
Class Methods
| Method | Description |
|---|---|
await OneLakeToolkit.create(command, *, environment, namespaces, env) |
Factory — spawn local fabmcp and load tools (stdio) |
await OneLakeToolkit.from_url(url, *, headers) |
Factory — connect to remote fabmcp server (HTTP/SSE) |
Instance Methods & Properties
| Member | Description |
|---|---|
get_context_tools() |
Return context-aware tools (recommended) |
get_tools(*, category=None) |
Return raw MCP tools, optionally filtered by category |
context |
The shared OneLakeContext instance |
tool_names |
Sorted list of raw tool names |
categories |
List of valid category names |
await close() |
Shut down the MCP server |
OneLakeContext
| Member | Description |
|---|---|
workspace_id / workspace_name |
Current workspace |
item_id / item_name / item_type |
Current item (lakehouse, warehouse, …) |
is_workspace_set() |
Returns True if a workspace is in context |
is_item_set() |
Returns True if both workspace and item are in context |
clear() |
Reset all context fields |
summary() |
Human-readable summary of current context |
Context Manager
async with OneLakeToolkit.create() as toolkit:
... # server shuts down automatically
Development
# Clone the repo
git clone https://github.com/microsoft/mcp.git
cd mcp/examples/langchain-onelake
# Install in development mode
pip install -e ".[dev,examples]"
# Run tests
pytest
# Lint
ruff check .
License
MIT — see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file langchain_onelake-0.2.0.tar.gz.
File metadata
- Download URL: langchain_onelake-0.2.0.tar.gz
- Upload date:
- Size: 30.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9cbb6588b601eb6d08fe930af01297a63e4267a8f3c8e873f5867a9c2942e551
|
|
| MD5 |
499f167f3529310ec5e2c49e70cc003a
|
|
| BLAKE2b-256 |
98392a14a66a7d52b9dad0390970222574690a690bec9b155faf258e2562952e
|
File details
Details for the file langchain_onelake-0.2.0-py3-none-any.whl.
File metadata
- Download URL: langchain_onelake-0.2.0-py3-none-any.whl
- Upload date:
- Size: 26.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71ba21ab7b3193150b4ef189a14c00dd7c12f52548d09f1fa266570ab069ae43
|
|
| MD5 |
19846fc7ce8b6cab76f7f69f76f41ca1
|
|
| BLAKE2b-256 |
30abf10ba807db3c34c7781d7671693087bb67c8770308a841041dcde44002dc
|