cancel
Showing results forย 
Search instead forย 
Did you mean:ย 
Generative AI
Explore discussions on generative artificial intelligence techniques and applications within the Databricks Community. Share ideas, challenges, and breakthroughs in this cutting-edge field.
cancel
Showing results forย 
Search instead forย 
Did you mean:ย 

Genie not able to list MCP prompts

sandyveeru
New Contributor

Hi community,

I'm building a custom MCP proxy server (hosted as a Databricks App) that forwards requests to an upstream MCP server. The upstream server exposes both **tools** and **prompts** as per the MCP specification.

I can confirm that Genie Code successfully discovers and calls tools via `tools/list` and `tools/call`. However, I'm unable to find any documentation or confirmation on whether Genie Code also supports the MCP **prompts** primitive โ€” specifically:

- Does Genie Code ever call `prompts/list` on a connected MCP server?
- Does Genie Code ever call `prompts/get` to invoke a specific prompt?
- If prompts are supported, how does Genie Code surface or use them in Agent mode?

The [MCP documentation on Databricks](https://docs.databricks.com/aws/en/generative-ai/mcp/) describes MCP as a standard for *"tools, resources, prompts, and other contextual information"*, but all concrete examples and limits (e.g. the 20-item cap) only reference tools. There is no explicit mention of prompt discovery or invocation in Genie Code.

**My setup:**
- Custom MCP server deployed as a Databricks App
- FastMCP with `stateless_http=True`
- Server correctly responds to `prompts/list` and `prompts/get` (verified via MCP Inspector)
- Genie Code connects successfully and uses tools, but no evidence of `prompts/list` being called

Has anyone confirmed whether MCP prompts are supported, planned, or intentionally out of scope for Genie Code? Any official reference or firsthand experience would be appreciated.

Thanks!

1 REPLY 1

iyashk-DB
Databricks Employee
Databricks Employee

This almost always turns out to be st.cache_resource on the connection, not the reverse proxy reusing anything.

You said you checked your st.cache_data functions and they key on username, which is the right instinct, but the leak usually hides in whatever function opens the SQL connection or session object. st.cache_resource caches are global by default, they're shared across every user and every session in the app process, not per-session like st.session_state. The cache key comes from the function's arguments, so if your connection-builder function looks like this:

@st.cache_resource(ttl=300)
def get_connection():
    return sql.connect(server_hostname=..., http_path=..., access_token=user_access_token)

every user hits the same cached connection object for up to the TTL window, and that connection was opened with whichever token happened to trigger the first cache miss. That's exactly the symptom you're describing: queries occasionally running under a previous user's identity, and it'll look "random" because it only shows up when the cache is warm from someone else's request.

The fix is to make the token part of the cache key so each identity gets its own cached object:

@st.cache_resource(ttl=300)
def get_connection(user_token: str):
    return sql.connect(server_hostname=..., http_path=..., access_token=user_token)

conn = get_connection(user_access_token)

Or simplest and safest, don't cache the connection at all, open it fresh per request and close it after the query, which is what Databricks' own Apps examples do for this exact reason.

To your second question, yes, there's a cheap way to verify the token belongs to who you think before you use it. Use the SDK with that specific token and check the identity it resolves to against X-Forwarded-Email:

from databricks.sdk import WorkspaceClient

w = WorkspaceClient(host=host, token=user_access_token)
me = w.current_user.me()
if me.user_name != username:
    st.error("Session identity mismatch, please refresh.")
    st.stop()

One more thing worth knowing separately from the caching issue: st.context.headers itself is only populated once, at the initial page load / WebSocket connection, and doesn't refresh on reruns. So on a long-lived tab, even without any caching bug, the token you're holding can go stale if the underlying session persists across a reconnect. The identity check above catches that case too, since it fails closed instead of quietly running a query under a token that no longer matches.