Skip to content

Commit c32d356

Browse files
jeromechooclaude
andcommitted
Fix enhance title param, repair test.sh, pin dependencies
Three pre-existing issues found while testing #2: enhance's `title` parameter never reached clients. FastMCP's schema compressor treats the properties map as a schema node when it contains a `type` key, then strips the sibling `title` as a JSON Schema annotation. The parameter is now `job_title` and is still sent upstream as `title`, so the Diffbot KG request is unchanged. test.sh silently exited 0 no matter what. It posted to /mcp/, which now 307-redirects to /mcp, and curl was not following redirects, so every run produced no output and looked like a pass. It now follows redirects, fails when no session is returned or when the tool call comes back isError, and takes URL/TOKEN overrides. Also adds the missing shebang. Dependencies were unpinned within their major, and every push to main rebuilds the image and redeploys, so an untested fastmcp or aiohttp release could reach production on an unrelated commit. Both are pinned to the patch level of the versions verified here. requires-python was also wrong: both dependencies need 3.10 or newer, not 3.8. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 3c868b9 commit c32d356

8 files changed

Lines changed: 223 additions & 28 deletions

File tree

diffbot_mcp.egg-info/PKG-INFO

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
Metadata-Version: 2.4
2+
Name: diffbot-mcp
3+
Version: 0.1.0
4+
Summary: A Diffbot MCP server with a variety of helpful web data handling tools for your agent or LLM pipeline.
5+
Requires-Python: >=3.10
6+
Description-Content-Type: text/markdown
7+
License-File: LICENSE
8+
Requires-Dist: fastmcp~=2.14.7
9+
Requires-Dist: aiohttp~=3.14.3
10+
Dynamic: license-file
11+
12+
# Diffbot MCP Server
13+
A Diffbot MCP server with a variety of helpful web data handling tools for your agent or LLM pipeline.
14+
15+
**What is Diffbot?**
16+
Diffbot is a small research company building AI that structure the web. Our products connect apps to the structured web automatically, like an API for all of the public web.
17+
18+
## Tools
19+
20+
#### 🧬 extract
21+
**Web fetch tool alternative.** Conventional fetch tools return either 500k+ tokens of HTML or a markdown approximation of the page's content. Extract classifies the page it is fetching and extracts content into a meaningful and consistent JSON structure. Responses are optimized for minimal token usage while maintaining data fidelity. Powered by [Diffbot Extract API](https://docs.diffbot.com/docs/getting-started-with-diffbot-extract).
22+
23+
#### 🔎 search_web
24+
**Web search tool that ranks accuracy, not popularity.** Built on Diffbot's first party web index. Ranking model heavily favors primary sources over secondary sources (e.g. press release > news piece on said press release). Returns markdown formatted content chunks for source citation. Optimized token management built-in.
25+
26+
#### 🪄 enhance
27+
**Web lookup tool for organizations and people.** Unlike web search, `enhance` will return structured data from the Diffbot Knowledge Graph on an organization or person (by name, url, or other acceptable input). Helpful for verifying facts, market research, or sales intelligence workflows.
28+
29+
## Authentication
30+
A free Diffbot token is required for tool use. [Get one here.](https://app.diffbot.com/get-started)
31+
32+
## Get Started
33+
34+
### Quick Start
35+
36+
The easiest way to get started is to connect your MCP client directly to the remote MCP server hosted by Diffbot.
37+
38+
```
39+
https://mcp.diffbot.com/mcp?token=<YOUR_DIFFBOT_TOKEN>
40+
```
41+
42+
This repo deploys directly to the remote server.
43+
44+
### Local Installation
45+
46+
Clone the repository
47+
```bash
48+
git clone git@github.com:diffbot/diffbot-mcp.git
49+
```
50+
51+
Install requirements
52+
```bash
53+
pip install .
54+
```
55+
56+
You can now run the server with `python3 diffbot_mcp_server.py`, or skip this step if you will be setting this server up with an MCP client.
57+
58+
#### (Optional) Docker Install
59+
60+
Build the image
61+
```bash
62+
docker build -t diffbot-mcp .
63+
```
64+
65+
### Setup with MCP Clients
66+
67+
To setup Claude Desktop, follow the [official installation guide](https://modelcontextprotocol.io/docs/develop/connect-local-servers) and use this example `claude_desktop_config.json` configuration (replace variables as needed).
68+
69+
This standard config works with most IDEs and environments.
70+
71+
```json
72+
{
73+
"mcpServers": {
74+
"diffbot-mcp": {
75+
"command": "python3",
76+
"args": [
77+
"/<YOUR_PROJECT_FOLDER>/diffbot-mcp/diffbot_mcp_server.py"
78+
],
79+
"env": {
80+
"DIFFBOT_TOKEN": "<YOUR_DIFFBOT_TOKEN>"
81+
}
82+
}
83+
}
84+
}
85+
```
86+
For Docker installs, follow this configuration.
87+
88+
```json
89+
{
90+
"mcpServers": {
91+
"diffbot-mcp": {
92+
"command": "docker",
93+
"args": [
94+
"run",
95+
"--rm",
96+
"-i",
97+
"-e", "DIFFBOT_TOKEN=<YOUR_DIFFBOT_TOKEN>",
98+
"diffbot-mcp"
99+
]
100+
}
101+
}
102+
}
103+
```
104+
105+
<details>
106+
<summary>Visual Studio Code / Copilot</summary>
107+
108+
For remote setup, simply enter the remote server URL and include "http" as the transport type.
109+
110+
```json
111+
{
112+
"servers": {
113+
"diffbot-mcp": {
114+
"type": "http",
115+
"url": "https://mcp.diffbot.com/mcp/?token=<YOUR_DIFFBOT_TOKEN>"
116+
}
117+
}
118+
}
119+
```
120+
121+
For local setup, try this modified config for better secrets management.
122+
123+
```json
124+
{
125+
"servers": {
126+
"diffbot-mcp": {
127+
"command": "python3",
128+
"args": [
129+
"/<YOUR_PROJECT_FOLDER>/diffbot-mcp/diffbot_mcp_server.py"
130+
],
131+
"env": {
132+
"DIFFBOT_TOKEN": "${input:diffbot-api-key}"
133+
}
134+
}
135+
},
136+
"inputs": [
137+
{
138+
"password": true,
139+
"id": "diffbot-api-key",
140+
"type": "promptString",
141+
"description": "Diffbot API Key"
142+
}
143+
]
144+
}
145+
```
146+
</details>
147+
148+
## Help & Support
149+
This project is built and maintained by [@jeromechoo](https://github.com/jeromechoo). For support, file an issue and he'll get back to you as soon as he can. For faster answers, write to [sales@diffbot.com](mailto:sales@diffbot.com) 😜.

diffbot_mcp.egg-info/SOURCES.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
LICENSE
2+
README.md
3+
diffbot_mcp_server.py
4+
pyproject.toml
5+
diffbot_mcp.egg-info/PKG-INFO
6+
diffbot_mcp.egg-info/SOURCES.txt
7+
diffbot_mcp.egg-info/dependency_links.txt
8+
diffbot_mcp.egg-info/requires.txt
9+
diffbot_mcp.egg-info/top_level.txt
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

diffbot_mcp.egg-info/requires.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
fastmcp~=2.14.7
2+
aiohttp~=3.14.3

diffbot_mcp.egg-info/top_level.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
diffbot_mcp_server

diffbot_mcp_server.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@ async def enhance(
9595
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,
9696
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,
9797
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,
98-
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,
98+
# Named job_title rather than title: a parameter named "title" alongside one
99+
# named "type" is stripped from the advertised tool schema, because the schema
100+
# compressor reads the properties map as a schema node and treats the sibling
101+
# "title" as the JSON Schema annotation. Sent upstream as "title" regardless.
102+
job_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,
99103
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
100104
) -> dict:
101105

@@ -116,8 +120,8 @@ async def enhance(
116120
params["email"] = email
117121
if employer and type == "Person":
118122
params["employer"] = employer
119-
if title and type == "Person":
120-
params["title"] = title
123+
if job_title and type == "Person":
124+
params["title"] = job_title
121125
if school and type == "Person":
122126
params["school"] = school
123127

pyproject.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ name = "diffbot-mcp"
33
version = "0.1.0"
44
description = "A Diffbot MCP server with a variety of helpful web data handling tools for your agent or LLM pipeline."
55
readme = "README.md"
6-
requires-python = ">=3.8"
6+
requires-python = ">=3.10"
7+
# Pinned to the patch level: every push to main rebuilds the image and redeploys,
8+
# so an unpinned minor lets an untested dependency release reach production on a
9+
# commit that never touched it.
710
dependencies = [
8-
"fastmcp~=2.0",
9-
"aiohttp~=3.0"
11+
"fastmcp~=2.14.7",
12+
"aiohttp~=3.14.3"
1013
]

test.sh

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,53 @@
1+
#!/usr/bin/env bash
2+
# Smoke test for a locally running server: initialize a session, then call search_web.
3+
# Override the defaults as needed, e.g. TOKEN=<your-diffbot-token> ./test.sh
4+
set -uo pipefail
5+
6+
URL="${URL:-http://127.0.0.1:8000/mcp}"
7+
TOKEN="${TOKEN:-TEST}"
8+
ENDPOINT="$URL?token=$TOKEN"
9+
10+
# -L so the request survives the trailing-slash redirect fastmcp applies to /mcp/
11+
curl_mcp() {
12+
curl -sL \
13+
-H 'Content-Type: application/json' \
14+
-H 'Accept: application/json, text/event-stream' \
15+
"$@"
16+
}
17+
118
# initialize and capture session ID
2-
SESSION=$(curl -sD - \
3-
-H 'Content-Type: application/json' \
4-
-H 'Accept: application/json, text/event-stream' \
5-
-d '{"jsonrpc":"2.0","id":0,"method":"initialize",
6-
"params":{"protocolVersion":"2025-06-18",
7-
"capabilities":{"tools":{}},
8-
"clientInfo":{"name":"curl","version":"1"}}}' \
9-
http://127.0.0.1:8000/mcp/?token=TEST |
10-
grep -i mcp-session-id | awk '{print $2}' | tr -d '\r')
19+
SESSION=$(curl_mcp -D - \
20+
-d '{"jsonrpc":"2.0","id":0,"method":"initialize",
21+
"params":{"protocolVersion":"2025-06-18",
22+
"capabilities":{"tools":{}},
23+
"clientInfo":{"name":"curl","version":"1"}}}' \
24+
"$ENDPOINT" |
25+
grep -i '^mcp-session-id' | awk '{print $2}' | tr -d '\r')
26+
27+
if [ -z "$SESSION" ]; then
28+
echo "FAIL: no session ID returned from $URL — is the server running?" >&2
29+
exit 1
30+
fi
1131

1232
# send initialized notification
13-
curl -s \
14-
-H 'Content-Type: application/json' \
15-
-H 'Accept: application/json, text/event-stream' \
16-
-H "Mcp-Session-Id: $SESSION" \
17-
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
18-
http://127.0.0.1:8000/mcp/?token=TEST
33+
curl_mcp \
34+
-H "Mcp-Session-Id: $SESSION" \
35+
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
36+
"$ENDPOINT"
1937

2038
# call the search tool
21-
curl -s \
22-
-H 'Content-Type: application/json' \
23-
-H 'Accept: application/json, text/event-stream' \
24-
-H "Mcp-Session-Id: $SESSION" \
25-
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
26-
"params":{"name":"search_web","arguments":{"query":"diffbot"}}}' \
27-
http://127.0.0.1:8000/mcp/?token=TEST
39+
RESPONSE=$(curl_mcp \
40+
-H "Mcp-Session-Id: $SESSION" \
41+
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
42+
"params":{"name":"search_web","arguments":{"query":"diffbot"}}}' \
43+
"$ENDPOINT")
44+
45+
echo "$RESPONSE"
46+
47+
# the server reports tool failures in-band, so a 200 alone does not mean success
48+
if [ -z "$RESPONSE" ] || echo "$RESPONSE" | grep -q '"isError":true'; then
49+
echo "FAIL: search_web did not return a successful result" >&2
50+
exit 1
51+
fi
52+
53+
echo "PASS: search_web returned a result"

0 commit comments

Comments
 (0)