Created
August 21, 2026 12:42
-
-
Save quantumproxies/572de9b2f727dc61370c2303a6b52338 to your computer and use it in GitHub Desktop.
Give Claude live web access with two tool definitions — QuanticData + the Claude API https://quanticdata.io/blog/how-to-use-claude-api/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """A Claude tool loop with real web access, in one file. | |
| pip install anthropic requests | |
| export ANTHROPIC_API_KEY=sk-ant-... QD_API_KEY=qd_live_... | |
| python3 qd_claude_tools.py "What changed in the EU AI Act timeline this month?" | |
| Two tools is enough: search to FIND, scrape to READ. A search costs $0.0005 and a page | |
| $0.0002, so a six-source turn is about a thousandth of what the model tokens cost. | |
| https://quanticdata.io/web-data-api-for-ai/ · https://quanticdata.io/blog/how-to-use-claude-api/ | |
| Prefer no plumbing at all? https://github.com/quantumproxies/quanticdata-mcp-server | |
| """ | |
| import json | |
| import os | |
| import sys | |
| import requests | |
| from anthropic import Anthropic | |
| MODEL = os.environ.get("ANTHROPIC_MODEL", "claude-sonnet-5") | |
| BASE = "https://api.quanticdata.io/v1" | |
| QD = {"Authorization": f"Bearer {os.environ['QD_API_KEY']}"} | |
| TOOLS = [ | |
| { | |
| "name": "search", | |
| "description": ("Search the live web and get organic results with title, link and " | |
| "snippet. Finds pages; does not return their content."), | |
| "input_schema": { | |
| "type": "object", | |
| "properties": {"query": {"type": "string"}, | |
| "country": {"type": "string", "description": "ISO code, e.g. us"}}, | |
| "required": ["query"], | |
| }, | |
| }, | |
| { | |
| "name": "scrape", | |
| "description": ("Read one URL as clean Markdown, boilerplate removed. Pass `query` to " | |
| "get only the passages relevant to a question."), | |
| "input_schema": { | |
| "type": "object", | |
| "properties": {"url": {"type": "string"}, "query": {"type": "string"}}, | |
| "required": ["url"], | |
| }, | |
| }, | |
| ] | |
| def run_tool(name, args): | |
| if name == "search": | |
| p = requests.post(f"{BASE}/serp", headers=QD, timeout=120, | |
| json={"query": args["query"], "country": args.get("country"), | |
| "num": 10}).json().get("payload", {}) | |
| return json.dumps([{k: r.get(k) for k in ("position", "title", "link", "snippet")} | |
| for r in (p.get("organic") or [])]) | |
| body = {"url": args["url"], "format": "markdown", "contentMode": "article", | |
| "max_tokens": 1500} | |
| if args.get("query"): | |
| body |= {"query": args["query"], "highlights": True} | |
| p = requests.post(f"{BASE}/scrape", headers=QD, json=body, timeout=180).json().get("payload", {}) | |
| highlights = p.get("highlights") | |
| text = "\n\n".join(h.get("text", "") for h in highlights) if highlights else p.get("markdown", "") | |
| return f"source: {args['url']}\n\n{text}" | |
| client = Anthropic() | |
| messages = [{"role": "user", "content": " ".join(sys.argv[1:]) or "What is an MCP server?"}] | |
| system = ("You have live web access. Search to find sources, scrape to read them, and cite the " | |
| "URL for every factual claim. If the tools did not answer, say so rather than guessing.") | |
| for _ in range(8): | |
| response = client.messages.create(model=MODEL, max_tokens=4096, system=system, | |
| tools=TOOLS, messages=messages) | |
| messages.append({"role": "assistant", "content": response.content}) | |
| for block in response.content: | |
| if block.type == "text" and block.text.strip(): | |
| print(block.text) | |
| calls = [b for b in response.content if b.type == "tool_use"] | |
| if not calls: | |
| break | |
| messages.append({"role": "user", "content": [ | |
| {"type": "tool_result", "tool_use_id": c.id, "content": run_tool(c.name, c.input)} | |
| for c in calls | |
| ]}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment