From 7191ae93caee59858e39c92e608d803c918454fe Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 01:37:14 +0000 Subject: [PATCH 1/2] fix: resolve request token instead of silently falling back to None get_http_request() already returns a Starlette Request, but it was being re-wrapped as if it were a scope mapping. Construction survives because HTTPConnection is a Mapping over scope, so the failure only surfaced on the first .headers access, where Headers.__init__ does self._list = scope["headers"] = list(scope["headers"]) and raises TypeError: 'Request' object does not support item assignment. The bare `except Exception: pass` swallowed that, leaving self.token at the env default, which is None on the hosted multi-tenant server. Use get_http_request() directly, drop the now-unused Request import, and narrow the handler to RuntimeError around the get_http_request() call only. RuntimeError is what fastmcp raises under stdio, which is the case the handler exists to cover; the DIFFBOT_TOKEN fallback is kept for it. Header and query-param parsing now sit outside the handler so real failures surface instead of being swallowed. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019czdCzXr51L4DmKN6wLz8K --- diffbot_mcp_server.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/diffbot_mcp_server.py b/diffbot_mcp_server.py index 55b617a..05e767b 100644 --- a/diffbot_mcp_server.py +++ b/diffbot_mcp_server.py @@ -2,7 +2,6 @@ import aiohttp from fastmcp import FastMCP, Context from fastmcp.server.dependencies import get_http_request -from starlette.requests import Request from typing import Annotated, Literal, Optional, List mcp = FastMCP(name="Diffbot MCP Server") @@ -13,17 +12,17 @@ class DiffbotAPI: def __init__(self): self.token = os.getenv('DIFFBOT_TOKEN') try: - request = Request(get_http_request()) - auth_header = request.headers.get('Authorization', '') - if auth_header.lower().startswith('bearer '): - self.token = auth_header[7:] - else: - token = request.query_params.get('token') - if token: - self.token = token - except Exception: + request = get_http_request() + except RuntimeError: # Not an http request, use token in env - pass + return + auth_header = request.headers.get('Authorization', '') + if auth_header.lower().startswith('bearer '): + self.token = auth_header[7:] + else: + token = request.query_params.get('token') + if token: + self.token = token @mcp.tool( name="extract", From 2f979b5d3d10f3dbdf7f3d340f3c62700b3f90ae Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 01:37:24 +0000 Subject: [PATCH 2/2] fix(enhance): give optional parameters None defaults so they are actually optional name, url, location, email, employer, title and school are declared Optional but had no defaults, so fastmcp marked all eight parameters required and a schema-following client could not build a valid call. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019czdCzXr51L4DmKN6wLz8K --- diffbot_mcp_server.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/diffbot_mcp_server.py b/diffbot_mcp_server.py index 05e767b..fff7ff8 100644 --- a/diffbot_mcp_server.py +++ b/diffbot_mcp_server.py @@ -90,13 +90,13 @@ async def search_web( async def enhance( type: Annotated[Literal["Person", "Organization"], "Select an entity type to look up. Required."], - name: Annotated[Optional[List[str]], "The name(s) of the entity to look up. Do not specify this key unless a value is provided."], - url: Annotated[Optional[List[str]], "The URL(s) of the entity to look up. Do not specify this key unless a value is provided."], - location: Annotated[Optional[str], "The location (e.g. Houston, Texas, United States) of the entity to look up. Do not specify this key unless a value is provided."], - email: Annotated[Optional[List[str]], "The email(s) of the entity to look up. Can only be used with type 'Person'. Do not specify this key unless a value is provided."], - employer: Annotated[Optional[str], "The employer name of the entity to look up. Can only be used with type 'Person'. Do not specify this key unless a value is provided."], - title: Annotated[Optional[str], "The current position/title/role of the entity to look up. Can only be used with type 'Person'. Do not specify this key unless a value is provided."], - school: Annotated[Optional[str], "Any previous educational institution associated with the entity to look up. Can only be used with type 'Person'. Do not specify this key unless a value is provided."] + name: Annotated[Optional[List[str]], "The name(s) of the entity to look up. Do not specify this key unless a value is provided."] = None, + url: Annotated[Optional[List[str]], "The URL(s) of the entity to look up. Do not specify this key unless a value is provided."] = None, + location: Annotated[Optional[str], "The location (e.g. Houston, Texas, United States) of the entity to look up. Do not specify this key unless a value is provided."] = None, + email: Annotated[Optional[List[str]], "The email(s) of the entity to look up. Can only be used with type 'Person'. Do not specify this key unless a value is provided."] = None, + employer: Annotated[Optional[str], "The employer name of the entity to look up. Can only be used with type 'Person'. Do not specify this key unless a value is provided."] = None, + title: Annotated[Optional[str], "The current position/title/role of the entity to look up. Can only be used with type 'Person'. Do not specify this key unless a value is provided."] = None, + school: Annotated[Optional[str], "Any previous educational institution associated with the entity to look up. Can only be used with type 'Person'. Do not specify this key unless a value is provided."] = None ) -> dict: diffbot = DiffbotAPI()