Skip to content

Commit 772cc56

Browse files
authored
Merge pull request #92 from agentic-community/feature/sre-gateway-integration-issue-91
Enhanced MCP Gateway & Registry with SRE Gateway Integration
2 parents 3e820e6 + 1f49c66 commit 772cc56

File tree

13 files changed

+987
-81
lines changed

13 files changed

+987
-81
lines changed

agents/.env.template

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ SECRET_KEY=your-secret-key-here
2424
# Either http://localhost:8000 or the HTTPS URL of your deployed MCP Gateway
2525
REGISTRY_URL=your_registry_url_here
2626

27-
ANTHROPIC_API_KEY=your_anthropic_api_key_here
27+
ANTHROPIC_API_KEY=your_anthropic_api_key_here
28+
29+
SRE_GATEWAY_AUTH_TOKEN=your_sre_gateway_auth_token_here

agents/agent.py

Lines changed: 79 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,32 @@
8181
# Get logger
8282
logger = logging.getLogger(__name__)
8383

84+
# Global constant for default MCP tool name to filter and use
85+
DEFAULT_MCP_TOOL_NAME = "intelligent_tool_finder"
86+
87+
88+
def enable_verbose_logging():
89+
"""Enable verbose debug logging for HTTP libraries and main logger."""
90+
# Set main logger to DEBUG level
91+
logger.setLevel(logging.DEBUG)
92+
93+
# Enable debug logging for httpx to see request/response details
94+
httpx_logger = logging.getLogger("httpx")
95+
httpx_logger.setLevel(logging.DEBUG)
96+
httpx_logger.propagate = True
97+
98+
# Enable debug logging for httpcore (underlying HTTP library)
99+
httpcore_logger = logging.getLogger("httpcore")
100+
httpcore_logger.setLevel(logging.DEBUG)
101+
httpcore_logger.propagate = True
102+
103+
# Enable debug logging for mcp client libraries
104+
mcp_logger = logging.getLogger("mcp")
105+
mcp_logger.setLevel(logging.DEBUG)
106+
mcp_logger.propagate = True
107+
108+
logger.info("Verbose logging enabled for httpx, httpcore, mcp libraries, and main logger")
109+
84110
def get_auth_mode_from_args() -> tuple[bool, str, str]:
85111
"""
86112
Parse command line arguments to determine authentication mode and env file names.
@@ -231,6 +257,14 @@ def parse_arguments() -> argparse.Namespace:
231257
parser.add_argument('--message', type=str, default='what is the current time in Clarksburg, MD',
232258
help='Message to send to the agent')
233259

260+
# MCP tool filtering arguments
261+
parser.add_argument('--mcp-tool-name', type=str, default=DEFAULT_MCP_TOOL_NAME,
262+
help=f'Name of the MCP tool to filter and use (default: {DEFAULT_MCP_TOOL_NAME})')
263+
264+
# Verbose logging argument
265+
parser.add_argument('--verbose', '-v', action='store_true',
266+
help='Enable verbose HTTP debugging output')
267+
234268
# Authentication method arguments
235269
parser.add_argument('--use-session-cookie', action='store_true',
236270
help='Use session cookie authentication instead of M2M')
@@ -261,6 +295,10 @@ def parse_arguments() -> argparse.Namespace:
261295

262296
args = parser.parse_args()
263297

298+
# Enable verbose logging if requested
299+
if args.verbose:
300+
enable_verbose_logging()
301+
264302
# Validate authentication parameters based on method
265303
if args.use_session_cookie:
266304
# For session cookie auth, we just need the cookie file
@@ -394,19 +432,29 @@ async def invoke_mcp_tool(mcp_registry_url: str, server_name: str, tool_name: st
394432
}
395433

396434
# TRACE: Print all parameters received by invoke_mcp_tool
397-
logger.info(f"invoke_mcp_tool TRACE - Parameters received:")
398-
logger.info(f" mcp_registry_url: {mcp_registry_url}")
399-
logger.info(f" server_name: {server_name}")
400-
logger.info(f" tool_name: {tool_name}")
401-
logger.info(f" arguments: {arguments}")
402-
logger.info(f" auth_token: {auth_token[:50] if auth_token else 'None'}...")
403-
logger.info(f" user_pool_id: {user_pool_id}")
404-
logger.info(f" client_id: {client_id}")
405-
logger.info(f" region: {region}")
406-
logger.info(f" auth_method: {auth_method}")
407-
logger.info(f" session_cookie: {session_cookie}")
408-
logger.info(f" supported_transports: {supported_transports}")
409-
logger.info(f"invoke_mcp_tool TRACE - Headers built: {headers}")
435+
logger.debug(f"invoke_mcp_tool TRACE - Parameters received:")
436+
logger.debug(f" mcp_registry_url: {mcp_registry_url}")
437+
logger.debug(f" server_name: {server_name}")
438+
logger.debug(f" tool_name: {tool_name}")
439+
logger.debug(f" arguments: {arguments}")
440+
logger.debug(f" auth_token: {auth_token[:50] if auth_token else 'None'}...")
441+
logger.debug(f" user_pool_id: {user_pool_id}")
442+
logger.debug(f" client_id: {client_id}")
443+
logger.debug(f" region: {region}")
444+
logger.debug(f" auth_method: {auth_method}")
445+
logger.debug(f" session_cookie: {session_cookie}")
446+
logger.debug(f" supported_transports: {supported_transports}")
447+
logger.debug(f"invoke_mcp_tool TRACE - Headers built: {headers}")
448+
449+
# Check for server-specific AUTH_TOKEN environment variable
450+
# Convert server_name to env var format: /sre-gateway -> SRE_GATEWAY_AUTH_TOKEN
451+
server_env_name = server_name.strip('/').upper().replace('-', '_') + '_AUTH_TOKEN'
452+
server_auth_token = os.environ.get(server_env_name)
453+
454+
if server_auth_token:
455+
logger.info(f"Found server-specific auth token in environment variable: {server_env_name}")
456+
# Use the server-specific token for Authorization header
457+
headers['Authorization'] = f'Bearer {server_auth_token}'
410458

411459
if auth_method == "session_cookie" and session_cookie:
412460
headers['Cookie'] = f'mcp_gateway_session={session_cookie}'
@@ -416,10 +464,16 @@ async def invoke_mcp_tool(mcp_registry_url: str, server_name: str, tool_name: st
416464
'X-Client-Id': redact_sensitive_value(client_id) if client_id else '',
417465
'X-Region': region or 'us-east-1'
418466
}
467+
if server_auth_token:
468+
redacted_headers['Authorization'] = f'Bearer {redact_sensitive_value(server_auth_token)}'
419469
else:
420-
headers['Authorization'] = f'Bearer {auth_token}'
470+
headers['X-Authorization'] = f'Bearer {auth_token}'
471+
# If no server-specific token, use the general auth_token
472+
if not server_auth_token:
473+
headers['Authorization'] = f'Bearer {auth_token}'
421474
redacted_headers = {
422-
'Authorization': f'Bearer {redact_sensitive_value(auth_token)}',
475+
'Authorization': f'Bearer {redact_sensitive_value(server_auth_token or auth_token)}',
476+
'X-Authorization': f'Bearer {redact_sensitive_value(auth_token)}',
423477
'X-User-Pool-Id': redact_sensitive_value(user_pool_id) if user_pool_id else '',
424478
'X-Client-Id': redact_sensitive_value(client_id) if client_id else '',
425479
'X-Region': region or 'us-east-1'
@@ -707,7 +761,8 @@ async def main():
707761
model = ChatAnthropic(
708762
model=args.model,
709763
api_key=anthropic_api_key,
710-
temperature=0
764+
temperature=0,
765+
max_tokens=8192,
711766
)
712767

713768
try:
@@ -722,7 +777,7 @@ async def main():
722777
else:
723778
# For both M2M and pre-generated JWT tokens
724779
auth_headers = {
725-
'Authorization': f'Bearer {access_token}',
780+
'X-Authorization': f'Bearer {access_token}',
726781
'X-User-Pool-Id': args.user_pool_id,
727782
'X-Client-Id': args.client_id,
728783
'X-Region': args.region
@@ -731,7 +786,7 @@ async def main():
731786
# Log redacted headers
732787
redacted_headers = {}
733788
for k, v in auth_headers.items():
734-
if k in ['Authorization', 'Cookie', 'X-User-Pool-Id', 'X-Client-Id']:
789+
if k in ['X-Authorization', 'Cookie', 'X-User-Pool-Id', 'X-Client-Id']:
735790
redacted_headers[k] = redact_sensitive_value(v) if v else ''
736791
else:
737792
redacted_headers[k] = v
@@ -755,9 +810,12 @@ async def main():
755810
mcp_tools = await client.get_tools()
756811
logger.info(f"Available MCP tools: {[tool.name for tool in mcp_tools]}")
757812

758-
# Add the calculator and invoke_mcp_tool to the tools array
759-
# The invoke_mcp_tool function already supports authentication parameters
760-
all_tools = [calculator, invoke_mcp_tool] + mcp_tools
813+
# Filter MCP tools to only include the specified tool
814+
filtered_tools = [tool for tool in mcp_tools if tool.name == args.mcp_tool_name]
815+
logger.info(f"Filtered MCP tools ({args.mcp_tool_name} only): {[tool.name for tool in filtered_tools]}")
816+
817+
# Add only the calculator, invoke_mcp_tool, and the specified MCP tool to the tools array
818+
all_tools = [calculator, invoke_mcp_tool] + filtered_tools
761819
logger.info(f"All available tools: {[tool.name if hasattr(tool, 'name') else tool.__name__ for tool in all_tools]}")
762820

763821
# Create the agent with the model and all tools

agents/system_prompt.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ You have direct access to these built-in tools:
1616
- And other specialized capabilities that may be available
1717

1818
When using intelligent_tool_finder and invoke_mcp_tool:
19-
1. Use intelligent_tool_finder to discover tools: `intelligent_tool_finder("description of needed capability")`
19+
1. Use intelligent_tool_finder to discover tools with maximum scope: `intelligent_tool_finder("description of needed capability", top_k_services=500, top_n_tools=5000)`
2020
2. Always use the "service_path" field from the finder results as the server_name parameter
2121
3. Use invoke_mcp_tool with the discovered information:
2222

auth_server/scopes.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,36 @@ mcp-servers-unrestricted/read:
116116
tools:
117117
- get_stock_aggregates
118118
- print_stock_data
119+
- server: sre-gateway
120+
methods:
121+
- initialize
122+
- notifications/initialized
123+
- ping
124+
- tools/list
125+
- tools/call
126+
tools:
127+
- x_amz_bedrock_agentcore_search
128+
- k8s-api___get_cluster_events
129+
- k8s-api___get_deployment_status
130+
- k8s-api___get_node_status
131+
- k8s-api___get_pod_status
132+
- k8s-api___get_resource_usage
133+
- logs-api___analyze_log_patterns
134+
- logs-api___count_log_events
135+
- logs-api___get_error_logs
136+
- logs-api___get_recent_logs
137+
- logs-api___search_logs
138+
- metrics-api___analyze_trends
139+
- metrics-api___get_availability_metrics
140+
- metrics-api___get_error_rates
141+
- metrics-api___get_performance_metrics
142+
- metrics-api___get_resource_metrics
143+
- runbooks-api___get_common_resolutions
144+
- runbooks-api___get_escalation_procedures
145+
- runbooks-api___get_incident_playbook
146+
- runbooks-api___get_troubleshooting_guide
147+
- runbooks-api___search_runbooks
148+
119149

120150
mcp-servers-unrestricted/execute:
121151
- server: auth_server
@@ -174,6 +204,35 @@ mcp-servers-unrestricted/execute:
174204
tools:
175205
- get_stock_aggregates
176206
- print_stock_data
207+
- server: sre-gateway
208+
methods:
209+
- initialize
210+
- notifications/initialized
211+
- ping
212+
- tools/list
213+
- tools/call
214+
tools:
215+
- x_amz_bedrock_agentcore_search
216+
- k8s-api___get_cluster_events
217+
- k8s-api___get_deployment_status
218+
- k8s-api___get_node_status
219+
- k8s-api___get_pod_status
220+
- k8s-api___get_resource_usage
221+
- logs-api___analyze_log_patterns
222+
- logs-api___count_log_events
223+
- logs-api___get_error_logs
224+
- logs-api___get_recent_logs
225+
- logs-api___search_logs
226+
- metrics-api___analyze_trends
227+
- metrics-api___get_availability_metrics
228+
- metrics-api___get_error_rates
229+
- metrics-api___get_performance_metrics
230+
- metrics-api___get_resource_metrics
231+
- runbooks-api___get_common_resolutions
232+
- runbooks-api___get_escalation_procedures
233+
- runbooks-api___get_incident_playbook
234+
- runbooks-api___get_troubleshooting_guide
235+
- runbooks-api___search_runbooks
177236

178237
mcp-servers-restricted/read:
179238
- server: auth_server

auth_server/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ async def validate_request(request: Request):
743743

744744
try:
745745
# Extract headers
746-
authorization = request.headers.get("Authorization")
746+
authorization = request.headers.get("X-Authorization")
747747
cookie_header = request.headers.get("Cookie", "")
748748
user_pool_id = request.headers.get("X-User-Pool-Id")
749749
client_id = request.headers.get("X-Client-Id")

docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ services:
1818
- COGNITO_CLIENT_SECRET=${COGNITO_CLIENT_SECRET}
1919
- COGNITO_USER_POOL_ID=${COGNITO_USER_POOL_ID}
2020
- AWS_REGION=${AWS_REGION:-us-east-1}
21+
- MCP_SERVER1_AUTH_TOKEN=${MCP_SERVER1_AUTH_TOKEN}
2122
ports:
2223
- "80:80"
2324
- "443:443"

docker/nginx_rev_proxy.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ server {
3434
proxy_set_header X-User-Pool-Id $http_x_user_pool_id;
3535
proxy_set_header X-Client-Id $http_x_client_id;
3636
proxy_set_header X-Region $http_x_region;
37+
proxy_set_header X-Authorization $http_x_authorization;
38+
3739

3840
# Pass all original headers (including Authorization and X-Body from Lua)
3941
proxy_pass_request_headers on;
@@ -187,6 +189,7 @@ server {
187189
proxy_set_header X-User-Pool-Id $http_x_user_pool_id;
188190
proxy_set_header X-Client-Id $http_x_client_id;
189191
proxy_set_header X-Region $http_x_region;
192+
proxy_set_header X-Authorization $http_x_authorization;
190193

191194
# Pass all original headers (including Authorization and X-Body from Lua)
192195
proxy_pass_request_headers on;

docker/registry-entrypoint.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,20 @@ else
112112
echo "Model already exists, skipping download."
113113
fi
114114

115+
# --- Environment Variable Substitution for MCP Server Auth Tokens ---
116+
echo "Processing MCP Server configuration files..."
117+
for i in $(seq 1 99); do
118+
env_var_name="MCP_SERVER${i}_AUTH_TOKEN"
119+
env_var_value=$(eval echo \$$env_var_name)
120+
121+
if [ ! -z "$env_var_value" ]; then
122+
echo "Found $env_var_name, substituting in server JSON files..."
123+
# Replace the literal environment variable name with its value in all JSON files
124+
find /app/registry/servers -name "*.json" -type f -exec sed -i "s|$env_var_name|$env_var_value|g" {} \;
125+
fi
126+
done
127+
echo "MCP Server configuration processing completed."
128+
115129
# --- Start Background Services ---
116130
export EMBEDDINGS_MODEL_NAME=$EMBEDDINGS_MODEL_NAME
117131
export EMBEDDINGS_MODEL_DIMENSIONS=384

0 commit comments

Comments
 (0)