Skip to content

Commit cecfb06

Browse files
Merge pull request #13 from looker-open-source/add-looker-mcp-sample
Add looker mcp sample
2 parents 43252bb + 0f4aa3c commit cecfb06

5 files changed

Lines changed: 237 additions & 0 deletions

File tree

looker-mcp-sample/README.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Looker AI Agent Integration with ADK & MCP
2+
3+
A step-by-step guide to building a basic AI agent utilizing the Google Agent Development Kit (ADK) and Model Context Protocol (MCP) to interact with Looker connection.
4+
5+
---
6+
7+
## 1. Secure Looker API Credentials
8+
9+
To allow the MCP server to act on your behalf, obtain your Looker Client ID and Client Secret:
10+
1. Log into your Looker instance.
11+
2. Navigate to your **Account** settings to manage your credentials (contact your administrator if this option is not visible).
12+
3. Generate a **Client ID** and **Client Secret**.
13+
4. Set them as environment variables (e.g., in a `.env` file):
14+
```bash
15+
LOOKER_CLIENT_ID="your_client_id"
16+
LOOKER_CLIENT_SECRET="your_client_secret"
17+
LOOKER_BASE_URL="https://your-looker-instance.com"
18+
```
19+
20+
---
21+
22+
## 2. Set Up the Environment
23+
24+
Use the `uv` package manager (or `venv`) to create a Python virtual environment and install dependencies:
25+
26+
```bash
27+
# Create a new directory and navigate into it (if starting from scratch)
28+
mkdir looker-mcp-agent && cd looker-mcp-agent
29+
30+
# Create and activate a virtual environment
31+
python3 -m venv .venv
32+
source .venv/bin/activate
33+
34+
# Install Google ADK and required dependencies
35+
pip install google-adk mcp python-dotenv
36+
```
37+
38+
---
39+
40+
## 3. Initialize the Agent
41+
42+
If you are building on your own, use the Agent Development Kit (ADK) CLI to create the structure of your agent, if you are using this repository, skip to step 4.
43+
44+
```bash
45+
adk create basic-looker-agent
46+
```
47+
48+
This creates the project structure, including:
49+
- `agent.py`: The entrypoint for defining agent logic.
50+
- `.env`: A local file for managing environment variables.
51+
- `__init__.py` / setup configurations.
52+
53+
---
54+
55+
## 4. Define Tools in `tools.yaml`
56+
57+
Create a `tools.yaml` file in your project directory to define the Looker source and MCP tools:
58+
59+
```yaml
60+
sources:
61+
my-looker-source:
62+
kind: looker
63+
base_url: https://your-looker-instance.com
64+
client_id: $LOOKER_CLIENT_ID
65+
client_secret: $LOOKER_CLIENT_SECRET
66+
project: your-looker-project
67+
location: us-east1
68+
verify_ssl: true
69+
timeout: 600s
70+
71+
tools:
72+
get_connections:
73+
kind: looker-get-connections
74+
source: my-looker-source
75+
description: |
76+
Retrieves a list of all database connections configured in Looker.
77+
```
78+
79+
---
80+
81+
## 5. Implement the Agent (`agent.py`)
82+
83+
Modify `agent.py` to import MCP toolsets, initialize the standard I/O MCP server connection parameters, and configure the ADK `LlmAgent`.
84+
85+
```python
86+
import os
87+
from dotenv import load_dotenv
88+
from mcp import StdioServerParameters
89+
from google.adk.agents import LlmAgent
90+
from google.adk.tools import MCPToolset
91+
from google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams
92+
93+
# Load local environment variables
94+
load_dotenv()
95+
96+
# Set up MCP server parameters to invoke the database toolbox binary
97+
base_dir = os.path.dirname(os.path.abspath(__file__))
98+
toolbox_path = os.path.abspath(os.path.join(base_dir, "../toolbox"))
99+
tools_path = os.path.abspath(os.path.join(base_dir, "../tools.yaml"))
100+
101+
looker_server = StdioServerParameters(
102+
command=toolbox_path,
103+
args=["--stdio", "--tools-file", tools_path],
104+
env={
105+
"LOOKER_BASE_URL": os.getenv("LOOKER_BASE_URL"),
106+
"LOOKER_CLIENT_ID": os.getenv("LOOKER_CLIENT_ID"),
107+
"LOOKER_CLIENT_SECRET": os.getenv("LOOKER_CLIENT_SECRET"),
108+
},
109+
)
110+
111+
# Connect toolset to the agent
112+
looker_toolset = MCPToolset(
113+
connection_params=StdioConnectionParams(server_params=looker_server)
114+
)
115+
116+
# Define the LLM agent
117+
root_agent = LlmAgent(
118+
model='gemini-1.5-flash',
119+
name='looker_pro',
120+
description='A helpful assistant that helps query Looker and use mcp-toolbox-for-databases',
121+
instruction='You are a helpful assistant that helps retrieve the user with the Looker tools available to them.',
122+
tools=[looker_toolset],
123+
)
124+
```
125+
126+
---
127+
128+
## 6. Run and Test the Agent
129+
130+
Start the ADK web development server to interact with your agent locally:
131+
132+
```bash
133+
adk web
134+
```
135+
136+
1. Open the local connection URL in your browser.
137+
2. Ask the agent: *"What tools do you have available to you?"*
138+
3. Verify the agent lists `get_connections`.
139+
4. (Optional) To expand capabilities, add another Looker specific tool under the `tools` key in `tools.yaml`, restart the server using `adk web`, and test again.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
GOOGLE_API_KEY=your_google_api_key_here
2+
LOOKER_BASE_URL=https://your-instance.looker.com
3+
LOOKER_CLIENT_ID=your_client_id
4+
LOOKER_CLIENT_SECRET=your_client_secret
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import agent
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import os
2+
from dotenv import load_dotenv
3+
from mcp import StdioServerParameters
4+
from google.adk.agents import LlmAgent
5+
from google.adk.tools import ToolContext, MCPToolset
6+
from google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams
7+
8+
# =====================================================================
9+
# 1. ENVIRONMENT CONFIGURATION & VARIABLE LOADING
10+
# =====================================================================
11+
# Load configuration settings from the local `.env` file.
12+
13+
load_dotenv()
14+
15+
looker_client_id = os.getenv("LOOKER_CLIENT_ID")
16+
looker_client_secret = os.getenv("LOOKER_CLIENT_SECRET")
17+
looker_base_url = os.getenv("LOOKER_BASE_URL")
18+
19+
# =====================================================================
20+
# 2. CONFIGURING THE DATABASE/TOOL MCP SERVER (STDIO CONNECTION)
21+
# =====================================================================
22+
# Define standard I/O parameters for launching the `toolbox` server.
23+
24+
looker_server = StdioServerParameters(
25+
command="../toolbox",
26+
args=["--stdio", "--tools-file", "../tools.yaml"],
27+
env={
28+
"LOOKER_BASE_URL": looker_base_url,
29+
"LOOKER_CLIENT_ID": looker_client_id,
30+
"LOOKER_CLIENT_SECRET": looker_client_secret
31+
},
32+
)
33+
34+
# (Optional): Uncomment this code to check for missing environment varialbes
35+
#
36+
# missing_vars = [
37+
# name for name, val in {
38+
# "LOOKER_CLIENT_ID": looker_client_id,
39+
# "LOOKER_CLIENT_SECRET": looker_client_secret,
40+
# "LOOKER_BASE_URL": looker_base_url,
41+
# }.items()
42+
# if not val
43+
# ]
44+
# if missing_vars:
45+
# raise ValueError(f"Missing required environment variables: {', '.join(missing_vars)}")
46+
47+
48+
# Wrap the MCP server parameters into a Toolset that the ADK agent can use.
49+
50+
looker_toolset = MCPToolset(
51+
connection_params=StdioConnectionParams(server_params=looker_server)
52+
)
53+
54+
# =====================================================================
55+
# 3. INITIALIZING THE ADK AGENT WITH GEMINI 3.5 FLASH
56+
# =====================================================================
57+
# Initialize the core Looker agent (`LlmAgent`).
58+
# - We use the highly capable `gemini-3.5-flash` model.
59+
# - We equip it with the `looker_toolset` configured above.
60+
root_agent = LlmAgent(
61+
model='gemini-2.0-flash',
62+
name='looker_pro',
63+
description='A helpful assistant that connects to the Looker resources via mcp-toolbox-for-databases',
64+
instruction='You are a helpful assistant that helps write, edit, and improve high quality LookML files and manipulate Looker with MCP tools',
65+
tools=[looker_toolset],
66+
)

looker-mcp-sample/tools.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
sources:
2+
my-looker-source:
3+
kind: looker
4+
base_url: https://your-instance.looker.com
5+
client_id: $LOOKER_CLIENT_ID
6+
client_secret: $LOOKER_CLIENT_SECRET
7+
project: your-project-name
8+
location: us-east1
9+
verify_ssl: true
10+
timeout: 600s
11+
tools:
12+
get_connections:
13+
kind: looker-get-connections
14+
source: my-looker-source
15+
description: |
16+
This tool retrieves a list of all database connections configured in the Looker system.
17+
18+
Parameters:
19+
This tool takes no parameters.
20+
21+
Output:
22+
A JSON array of objects, each representing a database connection.
23+
create_dashboard:
24+
kind: looker-make-dashboard
25+
source: my-looker-source
26+
description: |
27+
This tool creates a dashboard from a prompt.

0 commit comments

Comments
 (0)