@macaw-ai/client 0.0.0-stage → 0.9.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/LICENSE.md +339 -0
  2. package/bin/install.js +278 -0
  3. package/package.json +37 -4
  4. package/payload/README.md +56 -0
  5. package/payload/secureAI/LICENSE +190 -0
  6. package/payload/secureAI/NOTICE +5 -0
  7. package/payload/secureAI/demos/policy-controls/1_uncontrolled.py +139 -0
  8. package/payload/secureAI/demos/policy-controls/2_with_macaw.py +139 -0
  9. package/payload/secureAI/demos/policy-controls/3_with_user_policies.py +162 -0
  10. package/payload/secureAI/demos/policy-controls/credentials.txt +12 -0
  11. package/payload/secureAI/demos/policy-controls/malicious_report.txt +21 -0
  12. package/payload/secureAI/demos/policy-controls/sales_report.txt +20 -0
  13. package/payload/secureAI/demos/tutorial-1-rbac/README.md +143 -0
  14. package/payload/secureAI/demos/tutorial-1-rbac/app.py +147 -0
  15. package/payload/secureAI/demos/tutorial-1-rbac/authprompts_demo.py +306 -0
  16. package/payload/secureAI/demos/tutorial-1-rbac/config/claims-config.yaml +152 -0
  17. package/payload/secureAI/demos/tutorial-1-rbac/demo_secureopenai_with_policies.py +150 -0
  18. package/payload/secureAI/demos/tutorial-1-rbac/policies/bu_Analytics.json +8 -0
  19. package/payload/secureAI/demos/tutorial-1-rbac/policies/company_FinTech_Corp.json +70 -0
  20. package/payload/secureAI/demos/tutorial-1-rbac/policies/llm-base.json +69 -0
  21. package/payload/secureAI/demos/tutorial-1-rbac/policies/team_Reporting.json +8 -0
  22. package/payload/secureAI/demos/tutorial-1-rbac/policies/user_alice.json +32 -0
  23. package/payload/secureAI/demos/tutorial-1-rbac/policies/user_bob.json +28 -0
  24. package/payload/secureAI/demos/tutorial-1-rbac/policies/user_carol.json +34 -0
  25. package/payload/secureAI/demos/tutorial-1-rbac/requirements.txt +6 -0
  26. package/payload/secureAI/demos/tutorial-1-rbac/setup/auth0_complete_setup.sh +392 -0
  27. package/payload/secureAI/demos/tutorial-1-rbac/setup/keycloak_complete_setup.sh +320 -0
  28. package/payload/secureAI/demos/tutorial-2-intent/Policies/alation-remote-proxy.json +155 -0
  29. package/payload/secureAI/demos/tutorial-2-intent/Policies/bu.json +22 -0
  30. package/payload/secureAI/demos/tutorial-2-intent/Policies/company.json +17 -0
  31. package/payload/secureAI/demos/tutorial-2-intent/Policies/user_alice.json +48 -0
  32. package/payload/secureAI/demos/tutorial-2-intent/Policies/user_bob.json +83 -0
  33. package/payload/secureAI/demos/tutorial-2-intent/README.md +213 -0
  34. package/payload/secureAI/demos/tutorial-2-intent/script.py +188 -0
  35. package/payload/secureAI/demos/tutorial-2-intent/setup/alation_verifier.py +177 -0
  36. package/payload/secureAI/demos/tutorial-2-intent/setup/get_alation_user_token.py +180 -0
  37. package/payload/secureAI/examples/README.md +244 -0
  38. package/payload/secureAI/examples/anthropic/anthropic_1a_dropin_simple.py +103 -0
  39. package/payload/secureAI/examples/anthropic/anthropic_1b_multiuser_bind.py +190 -0
  40. package/payload/secureAI/examples/anthropic/anthropic_1b_multiuser_bind_streaming.py +190 -0
  41. package/payload/secureAI/examples/anthropic/anthropic_1c_a2a_invoke.py +156 -0
  42. package/payload/secureAI/examples/attestations/1a_trade_alice.py +215 -0
  43. package/payload/secureAI/examples/attestations/1a_trade_bob.py +164 -0
  44. package/payload/secureAI/examples/attestations/1b_grant_admin.py +170 -0
  45. package/payload/secureAI/examples/attestations/1b_grant_researcher.py +231 -0
  46. package/payload/secureAI/examples/attestations/README.md +128 -0
  47. package/payload/secureAI/examples/langchain/langchain_1a_dropin_simple.py +199 -0
  48. package/payload/secureAI/examples/langchain/langchain_1b_multiuser.py +262 -0
  49. package/payload/secureAI/examples/langchain/langchain_1c_orchestration.py +332 -0
  50. package/payload/secureAI/examples/langchain/langchain_1d_llm_openai.py +130 -0
  51. package/payload/secureAI/examples/langchain/langchain_1e_llm_anthropic.py +130 -0
  52. package/payload/secureAI/examples/langchain/langchain_1f_memory.py +214 -0
  53. package/payload/secureAI/examples/litellm/litellm_1a_dropin_simple.py +131 -0
  54. package/payload/secureAI/examples/mcp/1a_simple_invocation.py +115 -0
  55. package/payload/secureAI/examples/mcp/1b_discovery_and_resources.py +142 -0
  56. package/payload/secureAI/examples/mcp/1c_logging_client.py +100 -0
  57. package/payload/secureAI/examples/mcp/1d_progress_client.py +100 -0
  58. package/payload/secureAI/examples/mcp/1e_sampling_client.py +150 -0
  59. package/payload/secureAI/examples/mcp/1e_sampling_server.py +90 -0
  60. package/payload/secureAI/examples/mcp/1f_elicitation_client.py +127 -0
  61. package/payload/secureAI/examples/mcp/1f_elicitation_server.py +73 -0
  62. package/payload/secureAI/examples/mcp/1g_roots_client.py +122 -0
  63. package/payload/secureAI/examples/mcp/1g_roots_server.py +85 -0
  64. package/payload/secureAI/examples/mcp/2a_proxy_snowflake.py +212 -0
  65. package/payload/secureAI/examples/mcp/2b_proxy_databricks.py +299 -0
  66. package/payload/secureAI/examples/mcp/2c_proxy_stdio_fetch.py +91 -0
  67. package/payload/secureAI/examples/mcp/2d_proxy_stdio_salesforce.py +119 -0
  68. package/payload/secureAI/examples/mcp/2e_proxy_multiuser.py +136 -0
  69. package/payload/secureAI/examples/mcp/2f_proxy_stdio_databricks.py +144 -0
  70. package/payload/secureAI/examples/mcp/3a_native_mcp_client.py +104 -0
  71. package/payload/secureAI/examples/mcp/3b_native_mcp_proxy.py +114 -0
  72. package/payload/secureAI/examples/mcp/3c_native_mcp_sampling.py +180 -0
  73. package/payload/secureAI/examples/mcp/3d_native_mcp_2026.py +135 -0
  74. package/payload/secureAI/examples/mcp/securemcp_calculator.py +248 -0
  75. package/payload/secureAI/examples/mcp/securemcp_server.py +75 -0
  76. package/payload/secureAI/examples/openai/openai_1a_dropin_simple.py +102 -0
  77. package/payload/secureAI/examples/openai/openai_1b_multiuser_bind.py +193 -0
  78. package/payload/secureAI/examples/openai/openai_1b_multiuser_bind_streaming.py +199 -0
  79. package/payload/secureAI/examples/openai/openai_1c_a2a_invoke.py +156 -0
  80. package/payload/secureAI/examples/openai/openai_1d_invocation_patterns.py +337 -0
  81. package/payload/secureAI/examples/phishing-resistance/1a_login_alice.py +180 -0
  82. package/payload/secureAI/examples/phishing-resistance/1b_trade_alice.py +241 -0
  83. package/payload/secureAI/examples/phishing-resistance/1b_trade_bob.py +164 -0
  84. package/payload/secureAI/examples/phishing-resistance/README.md +124 -0
  85. package/payload/secureAI/examples/phishing-resistance/get_token.py +114 -0
  86. package/payload/secureAI/examples/pydantic_ai/README.md +88 -0
  87. package/payload/secureAI/examples/pydantic_ai/policies/app_pydantic-agent.json +10 -0
  88. package/payload/secureAI/examples/pydantic_ai/pydanticai_1a_dropin_simple.py +90 -0
  89. package/payload/secureAI/examples/pydantic_ai/pydanticai_1b_model_routing.py +85 -0
  90. package/payload/secureAI/examples/pydantic_ai/pydanticai_1c_native_tools.py +83 -0
  91. package/payload/secureAI/examples/pydantic_ai/pydanticai_1d_multiuser_bind.py +104 -0
  92. package/payload/secureAI/examples/pydantic_ai/pydanticai_1e_mcp_compose.py +92 -0
  93. package/payload/secureAI/macaw_adapters/__init__.py +55 -0
  94. package/payload/secureAI/macaw_adapters/anthropic/REFERENCE.md +374 -0
  95. package/payload/secureAI/macaw_adapters/anthropic/__init__.py +22 -0
  96. package/payload/secureAI/macaw_adapters/anthropic/secure_anthropic.py +792 -0
  97. package/payload/secureAI/macaw_adapters/anthropic_ext_tools/__init__.py +25 -0
  98. package/payload/secureAI/macaw_adapters/anthropic_ext_tools/secure_anthropic.py +840 -0
  99. package/payload/secureAI/macaw_adapters/langchain/REFERENCE.md +234 -0
  100. package/payload/secureAI/macaw_adapters/langchain/__init__.py +100 -0
  101. package/payload/secureAI/macaw_adapters/langchain/_utils.py +83 -0
  102. package/payload/secureAI/macaw_adapters/langchain/agents.py +296 -0
  103. package/payload/secureAI/macaw_adapters/langchain/anthropic.py +456 -0
  104. package/payload/secureAI/macaw_adapters/langchain/callbacks.py +306 -0
  105. package/payload/secureAI/macaw_adapters/langchain/memory.py +352 -0
  106. package/payload/secureAI/macaw_adapters/langchain/openai.py +410 -0
  107. package/payload/secureAI/macaw_adapters/langchain/tools.py +174 -0
  108. package/payload/secureAI/macaw_adapters/litellm/README.md +216 -0
  109. package/payload/secureAI/macaw_adapters/litellm/__init__.py +143 -0
  110. package/payload/secureAI/macaw_adapters/litellm/secure_litellm.py +686 -0
  111. package/payload/secureAI/macaw_adapters/mcp/REFERENCE.md +460 -0
  112. package/payload/secureAI/macaw_adapters/mcp/__init__.py +65 -0
  113. package/payload/secureAI/macaw_adapters/mcp/_endpoint.py +193 -0
  114. package/payload/secureAI/macaw_adapters/mcp/_endpoint2.py +225 -0
  115. package/payload/secureAI/macaw_adapters/mcp/_serve.py +25 -0
  116. package/payload/secureAI/macaw_adapters/mcp/client.py +721 -0
  117. package/payload/secureAI/macaw_adapters/mcp/decorators.py +228 -0
  118. package/payload/secureAI/macaw_adapters/mcp/fastmcp_compat.py +353 -0
  119. package/payload/secureAI/macaw_adapters/mcp/mcp.py +785 -0
  120. package/payload/secureAI/macaw_adapters/mcp/proxy.py +626 -0
  121. package/payload/secureAI/macaw_adapters/mcp/server.py +317 -0
  122. package/payload/secureAI/macaw_adapters/mcp/subscriptions.py +450 -0
  123. package/payload/secureAI/macaw_adapters/openai/REFERENCE.md +368 -0
  124. package/payload/secureAI/macaw_adapters/openai/__init__.py +22 -0
  125. package/payload/secureAI/macaw_adapters/openai/secure_openai.py +833 -0
  126. package/payload/secureAI/macaw_adapters/openai_ext_tools/REFERENCE.md +368 -0
  127. package/payload/secureAI/macaw_adapters/openai_ext_tools/__init__.py +25 -0
  128. package/payload/secureAI/macaw_adapters/openai_ext_tools/secure_openai.py +876 -0
  129. package/payload/secureAI/macaw_adapters/pydantic_ai/__init__.py +36 -0
  130. package/payload/secureAI/macaw_adapters/pydantic_ai/_core.py +257 -0
  131. package/payload/secureAI/macaw_adapters/pydantic_ai/agent.py +218 -0
  132. package/payload/secureAI/macaw_adapters/pydantic_ai/model.py +99 -0
  133. package/payload/secureAI/macaw_adapters/pydantic_ai/toolset.py +86 -0
  134. package/payload/secureAI/test_harness_quick.py +296 -0
  135. package/wheels/macaw_adapters-0.9.10.1-py3-none-any.whl +0 -0
  136. package/wheels/macaw_client-0.9.10.1-cp312-cp312-macosx_11_0_arm64.whl +0 -0
  137. package/wheels/macaw_client-0.9.10.1-cp312-cp312-manylinux_2_17_x86_64.whl +0 -0
  138. package/wheels/macaw_client-0.9.10.1-cp314-cp314-macosx_11_0_arm64.whl +0 -0
  139. package/wheels/macaw_client-0.9.10.1-cp314-cp314-manylinux_2_17_x86_64.whl +0 -0
  140. package/wheels/macaw_client-0.9.10.1-cp314-cp314-win_amd64.whl +0 -0
  141. package/wheels/macaw_client-0.9.10.1-cp39-cp39-macosx_11_0_arm64.whl +0 -0
  142. package/README.md +0 -3
@@ -0,0 +1,299 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Example: SecureMCPProxy with Databricks MCP Server
4
+
5
+ Connect to Databricks MCP servers with MACAW security for:
6
+ - Vector Search (RAG queries)
7
+ - Genie Space (natural language data analysis)
8
+ - SQL execution
9
+ - Unity Catalog functions
10
+
11
+ Databricks MCP Options:
12
+ 1. Databricks Managed MCP Servers - HTTP-based, Unity Catalog integrated
13
+ 2. Community server (databricks-mcp-server PyPI) - stdio-based
14
+
15
+ This example focuses on Databricks Managed MCP Servers (HTTP).
16
+
17
+ Prerequisites:
18
+ 1. Databricks workspace (community edition is free)
19
+ 2. MCP servers enabled in workspace
20
+ 3. MACAW LocalAgent running
21
+ 4. Install: pip install macaw-adapters[mcp-proxy]
22
+
23
+ References:
24
+ - Managed MCP: https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp
25
+ - Unity Catalog: https://docs.databricks.com/en/data-governance/unity-catalog/
26
+
27
+ Usage:
28
+ export DATABRICKS_HOST="https://your-workspace.databricks.com"
29
+ export DATABRICKS_TOKEN="dapi..."
30
+ python 2d_proxy_databricks.py
31
+ """
32
+
33
+ import os
34
+ import logging
35
+
36
+ logging.basicConfig(level=logging.INFO)
37
+ logger = logging.getLogger(__name__)
38
+
39
+
40
+ def example_databricks_sql_proxy():
41
+ """
42
+ Connect to Databricks SQL MCP server through SecureMCPProxy.
43
+
44
+ Databricks Managed MCP servers use OAuth/PAT authentication
45
+ and expose SQL, Vector Search, Genie, and UC Functions.
46
+ """
47
+ from macaw_adapters.mcp import SecureMCPProxy
48
+
49
+ # Databricks workspace URL and token
50
+ workspace_host = os.environ.get(
51
+ "DATABRICKS_HOST",
52
+ "https://your-workspace.databricks.com"
53
+ )
54
+ token = os.environ.get("DATABRICKS_TOKEN", "")
55
+
56
+ # Databricks SQL MCP endpoint
57
+ # Pattern: https://<workspace>/api/2.0/mcp/sql
58
+ sql_mcp_url = f"{workspace_host}/api/2.0/mcp/sql"
59
+
60
+ # Create proxy with Databricks PAT authentication
61
+ proxy = SecureMCPProxy(
62
+ app_name="databricks-sql",
63
+ upstream_url=sql_mcp_url,
64
+ upstream_auth={
65
+ "type": "bearer",
66
+ "token": token
67
+ }
68
+ )
69
+
70
+ print(f"\n{proxy}")
71
+
72
+ # List discovered tools
73
+ print("\nDiscovered Databricks SQL tools:")
74
+ for tool in proxy.list_tools():
75
+ print(f" - {tool['name']}: {tool.get('description', '')[:60]}...")
76
+
77
+ # Example: Execute SQL query
78
+ try:
79
+ result = proxy.call_tool("execute_sql", {
80
+ "query": "SELECT current_user(), current_catalog(), current_schema()"
81
+ })
82
+ print(f"\nSQL result: {result}")
83
+ except ValueError as e:
84
+ print(f"\nSQL tool not available: {e}")
85
+ except Exception as e:
86
+ print(f"\nSQL error: {e}")
87
+
88
+
89
+ def example_databricks_vector_search():
90
+ """
91
+ Connect to Databricks Vector Search MCP server.
92
+
93
+ Use case: RAG applications querying indexed documents.
94
+ """
95
+ from macaw_adapters.mcp import SecureMCPProxy
96
+
97
+ workspace_host = os.environ.get("DATABRICKS_HOST", "https://your-workspace.databricks.com")
98
+ token = os.environ.get("DATABRICKS_TOKEN", "")
99
+
100
+ # Vector Search MCP endpoint
101
+ # Pattern: https://<workspace>/api/2.0/mcp/vector-search/{catalog}/{schema}/{index}
102
+ catalog = os.environ.get("DATABRICKS_CATALOG", "main")
103
+ schema = os.environ.get("DATABRICKS_SCHEMA", "default")
104
+ index_name = os.environ.get("DATABRICKS_VS_INDEX", "documents_index")
105
+
106
+ vs_mcp_url = f"{workspace_host}/api/2.0/mcp/vector-search/{catalog}/{schema}/{index_name}"
107
+
108
+ proxy = SecureMCPProxy(
109
+ app_name="databricks-vector-search",
110
+ upstream_url=vs_mcp_url,
111
+ upstream_auth={"type": "bearer", "token": token}
112
+ )
113
+
114
+ print(f"\n{proxy}")
115
+
116
+ # Example: Search documents
117
+ try:
118
+ result = proxy.call_tool("search", {
119
+ "query": "How do I configure Unity Catalog?",
120
+ "num_results": 5
121
+ })
122
+ print(f"\nVector search result: {result}")
123
+ except ValueError as e:
124
+ print(f"\nSearch tool not available: {e}")
125
+ except Exception as e:
126
+ print(f"\nSearch error: {e}")
127
+
128
+
129
+ def example_databricks_genie():
130
+ """
131
+ Connect to Databricks Genie Space MCP server.
132
+
133
+ Use case: Natural language queries over structured data.
134
+ """
135
+ from macaw_adapters.mcp import SecureMCPProxy
136
+
137
+ workspace_host = os.environ.get("DATABRICKS_HOST", "https://your-workspace.databricks.com")
138
+ token = os.environ.get("DATABRICKS_TOKEN", "")
139
+
140
+ # Genie Space MCP endpoint
141
+ # Pattern: https://<workspace>/api/2.0/mcp/genie/{genie_space_id}
142
+ genie_space_id = os.environ.get("DATABRICKS_GENIE_SPACE", "your-genie-space-id")
143
+
144
+ genie_mcp_url = f"{workspace_host}/api/2.0/mcp/genie/{genie_space_id}"
145
+
146
+ proxy = SecureMCPProxy(
147
+ app_name="databricks-genie",
148
+ upstream_url=genie_mcp_url,
149
+ upstream_auth={"type": "bearer", "token": token}
150
+ )
151
+
152
+ print(f"\n{proxy}")
153
+
154
+ # Example: Ask Genie a question
155
+ try:
156
+ result = proxy.call_tool("ask", {
157
+ "question": "What were the top 5 products by revenue last quarter?"
158
+ })
159
+ print(f"\nGenie result: {result}")
160
+ except ValueError as e:
161
+ print(f"\nGenie tool not available: {e}")
162
+ except Exception as e:
163
+ print(f"\nGenie error: {e}")
164
+
165
+
166
+ def example_databricks_multi_user():
167
+ """
168
+ Multi-user pattern: data analysts with different Unity Catalog permissions.
169
+
170
+ Use case: Data platform where teams have different catalog access.
171
+ """
172
+ from macaw_adapters.mcp import SecureMCPProxy
173
+ from macaw_client import MACAWClient
174
+
175
+ workspace_host = os.environ.get("DATABRICKS_HOST", "https://your-workspace.databricks.com")
176
+ token = os.environ.get("DATABRICKS_TOKEN", "")
177
+
178
+ # Service creates shared proxy
179
+ proxy = SecureMCPProxy(
180
+ app_name="databricks-data-platform",
181
+ upstream_url=f"{workspace_host}/api/2.0/mcp/sql",
182
+ upstream_auth={"type": "bearer", "token": token}
183
+ )
184
+
185
+ # Data Engineer - full access
186
+ engineer = MACAWClient(
187
+ user_name="data-engineer-sam",
188
+ jwt_token=os.environ.get("SAM_JWT", "sam-jwt"),
189
+ agent_type="user"
190
+ )
191
+ engineer.register()
192
+ engineer_proxy = proxy.bind_to_user(engineer)
193
+
194
+ # Analyst - read-only access
195
+ analyst = MACAWClient(
196
+ user_name="analyst-kim",
197
+ jwt_token=os.environ.get("KIM_JWT", "kim-jwt"),
198
+ agent_type="user"
199
+ )
200
+ analyst.register()
201
+ analyst_proxy = proxy.bind_to_user(analyst)
202
+
203
+ print("\nMulti-user Databricks access:")
204
+ print(f" Engineer (Sam): {engineer_proxy}")
205
+ print(f" Analyst (Kim): {analyst_proxy}")
206
+
207
+ # Sam can create tables
208
+ try:
209
+ result = engineer_proxy.call_tool("execute_sql", {
210
+ "statement": "CREATE TABLE IF NOT EXISTS analytics.metrics (id INT, value DOUBLE)"
211
+ })
212
+ print(f"\nSam's CREATE result: {result}")
213
+ except PermissionError as e:
214
+ print(f"\nSam denied: {e}")
215
+ except Exception as e:
216
+ print(f"\nSam error: {e}")
217
+
218
+ # Kim can only query
219
+ try:
220
+ result = analyst_proxy.call_tool("execute_sql", {
221
+ "statement": "SELECT * FROM analytics.metrics LIMIT 10"
222
+ })
223
+ print(f"\nKim's SELECT result: {result}")
224
+ except PermissionError as e:
225
+ print(f"\nKim denied: {e}")
226
+ except Exception as e:
227
+ print(f"\nKim error: {e}")
228
+
229
+
230
+ def setup_instructions():
231
+ """Print setup instructions for Databricks MCP."""
232
+ print("""
233
+ ================================================================================
234
+ Databricks Managed MCP Server Setup
235
+ ================================================================================
236
+
237
+ 1. Get Databricks workspace:
238
+ - Enterprise: Contact Databricks
239
+ - Community Edition (free): https://community.cloud.databricks.com
240
+
241
+ 2. Enable MCP in your workspace:
242
+ - Go to: Workspace > Agents > MCP Servers
243
+ - View available MCP endpoints
244
+
245
+ 3. Create Personal Access Token (PAT):
246
+ - User Settings > Developer > Access Tokens
247
+ - Generate new token with appropriate permissions
248
+
249
+ 4. Set environment variables:
250
+ export DATABRICKS_HOST="https://your-workspace.databricks.com"
251
+ export DATABRICKS_TOKEN="dapi..."
252
+
253
+ 5. MCP Endpoint Patterns:
254
+ - SQL: {host}/api/2.0/mcp/sql
255
+ - Vector Search: {host}/api/2.0/mcp/vector-search/{catalog}/{schema}/{index}
256
+ - Genie: {host}/api/2.0/mcp/genie/{genie_space_id}
257
+ - UC Functions: {host}/api/2.0/mcp/functions/{catalog}/{schema}/{function}
258
+
259
+ 6. Run this example:
260
+ python 2d_proxy_databricks.py
261
+
262
+
263
+ ALTERNATIVE: Community MCP Server (stdio-based)
264
+ -----------------------------------------------
265
+
266
+ For local development with stdio transport:
267
+
268
+ 1. Install: pip install databricks-mcp-server
269
+ 2. Run: uvx databricks-mcp-server@latest
270
+
271
+ Note: stdio servers require an HTTP bridge (mcp-proxy) for SecureMCPProxy.
272
+
273
+ ================================================================================
274
+ """)
275
+
276
+
277
+ if __name__ == "__main__":
278
+ print("=" * 60)
279
+ print("SecureMCPProxy + Databricks MCP Server")
280
+ print("=" * 60)
281
+
282
+ setup_instructions()
283
+
284
+ print("\n--- Example: Databricks SQL Proxy ---")
285
+ try:
286
+ example_databricks_sql_proxy()
287
+ except ConnectionError as e:
288
+ print(f"\nConnection failed: {e}")
289
+ print("Make sure Databricks workspace is accessible and MCP is enabled.")
290
+
291
+ # Uncomment to test other examples:
292
+ # print("\n--- Example: Vector Search ---")
293
+ # example_databricks_vector_search()
294
+
295
+ # print("\n--- Example: Genie Space ---")
296
+ # example_databricks_genie()
297
+
298
+ # print("\n--- Example: Multi-User Access ---")
299
+ # example_databricks_multi_user()
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Example: SecureMCPProxy with mcp-server-fetch (stdio transport)
4
+
5
+ Demonstrates SecureMCPProxy connecting to a standard MCP server via stdio.
6
+ This validates the stdio transport with a simple, credential-free MCP server.
7
+
8
+ Security Model:
9
+ - MACAW creates AuthenticatedContext for EACH invocation
10
+ - Even with persistent subprocess, each call gets fresh identity/policy/signature
11
+ - Solves the "shared context" problem in standard MCP
12
+
13
+ Prerequisites:
14
+ pip install mcp-server-fetch
15
+ pip install macaw-adapters[mcp-proxy]
16
+
17
+ Usage:
18
+ python 2e_proxy_stdio_fetch.py
19
+ """
20
+
21
+ import sys
22
+ import logging
23
+
24
+ logging.basicConfig(level=logging.INFO)
25
+ logger = logging.getLogger(__name__)
26
+
27
+
28
+ def main():
29
+ """Test SecureMCPProxy with mcp-server-fetch."""
30
+ from macaw_adapters.mcp import SecureMCPProxy
31
+
32
+ print("=" * 60)
33
+ print("SecureMCPProxy + mcp-server-fetch (stdio)")
34
+ print("=" * 60)
35
+
36
+ # Step 1: Check mcp-server-fetch is installed
37
+ print("\n1. Checking mcp-server-fetch installation...")
38
+ try:
39
+ import mcp_server_fetch
40
+ print(" OK: mcp-server-fetch is installed")
41
+ except ImportError:
42
+ print(" ERROR: mcp-server-fetch not installed")
43
+ print(" Fix: pip install mcp-server-fetch")
44
+ return 1
45
+
46
+ # Step 2: Create proxy with stdio transport
47
+ print("\n2. Creating SecureMCPProxy with stdio transport...")
48
+ try:
49
+ proxy = SecureMCPProxy(
50
+ app_name="fetch-stdio-test",
51
+ command=["python", "-m", "mcp_server_fetch"],
52
+ )
53
+ print(f" OK: {proxy}")
54
+ except Exception as e:
55
+ print(f" ERROR: {e}")
56
+ return 1
57
+
58
+ # Step 3: Discover tools
59
+ print("\n3. Discovering tools...")
60
+ tools = proxy.list_tools()
61
+ print(f" Found {len(tools)} tools:")
62
+ for tool in tools:
63
+ desc = tool.get('description', '')[:50]
64
+ print(f" - {tool['name']}: {desc}...")
65
+
66
+ if not tools:
67
+ print(" ERROR: No tools discovered")
68
+ return 1
69
+
70
+ # Step 4: Call fetch tool
71
+ print("\n4. Calling fetch tool (https://httpbin.org/html)...")
72
+ try:
73
+ result = proxy.call_tool("fetch", {"url": "https://httpbin.org/html"})
74
+ if result:
75
+ content = result.get('result', result) if isinstance(result, dict) else result
76
+ preview = str(content)[:200].replace('\n', ' ')
77
+ print(f" OK: {preview}...")
78
+ else:
79
+ print(" OK: (empty result)")
80
+ except Exception as e:
81
+ print(f" ERROR: {e}")
82
+ return 1
83
+
84
+ print("\n" + "=" * 60)
85
+ print("SUCCESS: SecureMCPProxy stdio transport works!")
86
+ print("=" * 60)
87
+ return 0
88
+
89
+
90
+ if __name__ == "__main__":
91
+ sys.exit(main())
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Example: SecureMCPProxy with Salesforce DX MCP (stdio transport)
4
+
5
+ Demonstrates SecureMCPProxy connecting to Salesforce DX CLI via stdio.
6
+ Salesforce DX MCP provides tools for org management, deployment, and queries.
7
+
8
+ Security Model:
9
+ - MACAW creates AuthenticatedContext for EACH invocation
10
+ - Even with persistent subprocess, each call gets fresh identity/policy/signature
11
+ - Salesforce operations are policy-enforced and audited
12
+
13
+ Prerequisites:
14
+ 1. Salesforce account (free Developer Edition: https://developer.salesforce.com/signup)
15
+ 2. Salesforce CLI: npm install -g @salesforce/cli
16
+ 3. Authenticated org: sf org login web
17
+ 4. MACAW: pip install macaw-adapters[mcp-proxy]
18
+
19
+ NOTE: This example requires a Salesforce account. Skip if you don't have one -
20
+ the stdio pattern is validated by 2e_proxy_stdio_fetch.py.
21
+
22
+ Usage:
23
+ python 2f_proxy_stdio_salesforce.py
24
+ """
25
+
26
+ import os
27
+ import sys
28
+ import shutil
29
+ import logging
30
+
31
+ logging.basicConfig(level=logging.INFO)
32
+ logger = logging.getLogger(__name__)
33
+
34
+
35
+ def main():
36
+ """Test SecureMCPProxy with Salesforce DX MCP."""
37
+ from macaw_adapters.mcp import SecureMCPProxy
38
+
39
+ print("=" * 60)
40
+ print("SecureMCPProxy + Salesforce DX MCP (stdio)")
41
+ print("=" * 60)
42
+
43
+ # Step 1: Check npx is available
44
+ print("\n1. Checking prerequisites...")
45
+ if not shutil.which("npx"):
46
+ print(" ERROR: npx not found")
47
+ print(" Fix: Install Node.js (https://nodejs.org)")
48
+ return 1
49
+ print(" OK: npx found")
50
+
51
+ # Check if sf CLI is available
52
+ if not shutil.which("sf"):
53
+ print(" WARNING: sf CLI not found")
54
+ print(" You may need to install: npm install -g @salesforce/cli")
55
+
56
+ # Step 2: Create proxy with stdio transport
57
+ print("\n2. Creating SecureMCPProxy with Salesforce DX...")
58
+ try:
59
+ proxy = SecureMCPProxy(
60
+ app_name="salesforce-dx",
61
+ command=["npx", "@salesforce/mcp", "--orgs", "DEFAULT", "--dynamic-tools"],
62
+ env={
63
+ "HOME": os.environ.get("HOME", ""),
64
+ "PATH": os.environ.get("PATH", ""),
65
+ }
66
+ )
67
+ print(f" OK: {proxy}")
68
+ except ConnectionError as e:
69
+ print(f" ERROR: Failed to connect: {e}")
70
+ print("\n Troubleshooting:")
71
+ print(" 1. Install @salesforce/mcp: npm install -g @salesforce/mcp")
72
+ print(" 2. Login to an org: sf org login web")
73
+ print(" 3. Set default org: sf config set target-org=<alias>")
74
+ return 1
75
+ except Exception as e:
76
+ print(f" ERROR: {e}")
77
+ return 1
78
+
79
+ # Step 3: Discover tools
80
+ print("\n3. Discovering Salesforce DX tools...")
81
+ tools = proxy.list_tools()
82
+ print(f" Found {len(tools)} tools:")
83
+ for tool in tools[:10]: # Show first 10
84
+ print(f" - {tool['name']}")
85
+ if len(tools) > 10:
86
+ print(f" ... and {len(tools) - 10} more")
87
+
88
+ if not tools:
89
+ print(" ERROR: No tools discovered")
90
+ return 1
91
+
92
+ # Step 4: Test tool calls
93
+ print("\n4. Testing tool calls...")
94
+
95
+ # Get current username (requires directory - use current dir)
96
+ try:
97
+ result = proxy.call_tool("get_username", {"directory": os.getcwd()})
98
+ content = result.get('result', result) if isinstance(result, dict) else result
99
+ print(f" get_username: {content}")
100
+ except Exception as e:
101
+ print(f" get_username error: {e}")
102
+
103
+ # List available tools (dynamic)
104
+ try:
105
+ result = proxy.call_tool("list_tools", {})
106
+ content = result.get('result', result) if isinstance(result, dict) else result
107
+ preview = str(content)[:300] if content else "(empty)"
108
+ print(f" list_tools: {preview}...")
109
+ except Exception as e:
110
+ print(f" list_tools error: {e}")
111
+
112
+ print("\n" + "=" * 60)
113
+ print("SUCCESS: SecureMCPProxy + Salesforce DX works!")
114
+ print("=" * 60)
115
+ return 0
116
+
117
+
118
+ if __name__ == "__main__":
119
+ sys.exit(main())
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Example: SecureMCPProxy Multi-User Pattern
4
+
5
+ Demonstrates bind_to_user() for multi-tenant SaaS applications.
6
+ The service maintains the upstream MCP connection, but each request
7
+ runs with a specific user's identity and policy.
8
+
9
+ Security Model:
10
+ - Service creates ONE proxy to the upstream MCP server
11
+ - Each user gets a BoundMCPProxy via bind_to_user()
12
+ - User's calls are: evaluated against their policy, signed with their identity, logged under their audit trail
13
+ - Even with shared subprocess, MACAW provides per-user isolation
14
+
15
+ Prerequisites:
16
+ 1. pip install mcp-server-fetch macaw-adapters[mcp-proxy]
17
+ 2. Identity Provider configured (Console -> Settings -> Identity Bridge)
18
+ 3. Test users: alice/Alice123!, bob/Bob@123!
19
+
20
+ Usage:
21
+ python 2g_proxy_multiuser.py
22
+
23
+ No IdP configured? Use simpler examples first:
24
+ python 2e_proxy_stdio_fetch.py
25
+ """
26
+
27
+ import os
28
+ import sys
29
+ import logging
30
+
31
+ logging.basicConfig(level=logging.INFO)
32
+ logger = logging.getLogger(__name__)
33
+
34
+
35
+ def main():
36
+ """Test multi-user SecureMCPProxy pattern."""
37
+ from macaw_adapters.mcp import SecureMCPProxy
38
+ from macaw_client import MACAWClient, RemoteIdentityProvider
39
+
40
+ print("=" * 60)
41
+ print("SecureMCPProxy Multi-User Pattern")
42
+ print("=" * 60)
43
+
44
+ # Step 1: Service creates shared proxy
45
+ print("\n1. Creating shared proxy (service-level)...")
46
+ try:
47
+ import mcp_server_fetch
48
+ except ImportError:
49
+ print(" ERROR: mcp-server-fetch not installed")
50
+ print(" Fix: pip install mcp-server-fetch")
51
+ return 1
52
+
53
+ try:
54
+ proxy = SecureMCPProxy(
55
+ app_name="shared-fetch-proxy",
56
+ command=["python", "-m", "mcp_server_fetch"],
57
+ )
58
+ print(f" OK: {proxy}")
59
+ except Exception as e:
60
+ print(f" ERROR: {e}")
61
+ return 1
62
+
63
+ # Step 2: Authenticate users
64
+ print("\n2. Authenticating users...")
65
+
66
+ users = {}
67
+ for username, password in [("alice", "Alice123!"), ("bob", "Bob@123!")]:
68
+ try:
69
+ print(f" Authenticating {username}...")
70
+ jwt_token, _ = RemoteIdentityProvider().login(username, password)
71
+
72
+ user = MACAWClient(
73
+ user_name=username,
74
+ iam_token=jwt_token,
75
+ agent_type="user",
76
+ app_name="mcp-multiuser-test"
77
+ )
78
+
79
+ if not user.register():
80
+ print(f" ERROR: Failed to register {username}")
81
+ continue
82
+
83
+ users[username] = user
84
+ print(f" OK: {username} -> {user.agent_id}")
85
+
86
+ except Exception as e:
87
+ print(f" ERROR: {username} authentication failed: {e}")
88
+ print(" Make sure IdP is configured in Console -> Settings -> Identity Bridge")
89
+ return 1
90
+
91
+ if len(users) < 2:
92
+ print("\n ERROR: Could not authenticate both users")
93
+ return 1
94
+
95
+ # Step 3: Create per-user bound proxies
96
+ print("\n3. Creating per-user proxies via bind_to_user()...")
97
+ alice_proxy = proxy.bind_to_user(users["alice"])
98
+ bob_proxy = proxy.bind_to_user(users["bob"])
99
+ print(f" Alice: {alice_proxy}")
100
+ print(f" Bob: {bob_proxy}")
101
+
102
+ # Step 4: Test user-specific calls
103
+ print("\n4. Testing user-specific tool calls...")
104
+
105
+ test_urls = [
106
+ ("alice", alice_proxy, "https://alice.example.com"),
107
+ ("bob", bob_proxy, "https://bob.example.com"),
108
+ ]
109
+
110
+ for username, user_proxy, url in test_urls:
111
+ print(f"\n {username.upper()}'s call to {url}:")
112
+ try:
113
+ result = user_proxy.call_tool("fetch", {"url": url})
114
+ preview = str(result)[:80].replace('\n', ' ')
115
+ print(f" OK: {preview}...")
116
+ print(f" (Policy: {username}'s policy applied)")
117
+ print(f" (Signed: {username}'s identity)")
118
+ print(f" (Audit: logged under {username})")
119
+ except PermissionError as e:
120
+ print(f" BLOCKED by policy: {e}")
121
+ except Exception as e:
122
+ print(f" ERROR: {e}")
123
+
124
+ print("\n" + "=" * 60)
125
+ print("SUCCESS: Multi-user SecureMCPProxy works!")
126
+ print("=" * 60)
127
+ print("\nKey points:")
128
+ print(" - Same subprocess, different identities")
129
+ print(" - Each call has fresh AuthenticatedContext")
130
+ print(" - Policy enforcement per user")
131
+ print(" - Audit trail tracks who did what")
132
+ return 0
133
+
134
+
135
+ if __name__ == "__main__":
136
+ sys.exit(main())