LangChain integration
What you get
Use LangChain with KeepBal discovery, inspection and paid tool execution through one key and prepaid wallet.
Prerequisites
Create a KeepBal account and API key. Signup includes $1 credit once. Keep the key private and ensure sufficient wallet credit before executing a tool.
Setup
Install Python and run: pip install langchain-mcp-adapters langgraph "langchain[openai]". Export KEEPBAL_API_KEY and OPENAI_API_KEY; the latter authenticates the separately billed agent model in this example. The official README notes MCP support moved to langchain[mcp] / langchain.mcp; this example uses the documented adapters package.
import asyncio
import os
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain.agents import create_agent
async def main():
client = MultiServerMCPClient({"keepbal": {
"transport": "streamable_http",
"url": "https://keepbal.com/mcp",
"headers": {"Authorization": f"Bearer {os.environ['KEEPBAL_API_KEY']}"}
}})
tools = await client.get_tools()
agent = create_agent("openai:gpt-4.1", tools)
result = await agent.ainvoke({"messages": [{"role": "user", "content": "Inspect exa/contents, then fetch https://example.com with text enabled and summarize it."}]})
print(result)
asyncio.run(main())
Check that get_tools returns search_tools, inspect_tool, run_tool and get_run. Headers are supported for HTTP transports. If the model fails separately, check its model-provider credential.
LangChain official documentation
Worked example: read a web page
Ask your agent: Find the page-content tool, inspect exa/contents, then fetch https://example.com with text enabled and summarize the result. Review the published price before approving execution. Data is from Exa; this does not imply partnership.
search_tools {"query":"page contents"}
inspect_tool {"tool":"exa/contents"}
run_tool {"tool":"exa/contents","input":{"body":{"urls":["https://example.com"],"text":true}}}
These are MCP tool names and argument objects. The client wraps them in tools/call requests. If run_tool returns pending with a run_id, call get_run {"run_id":"RETURNED_RUN_ID"}; do not repeat run_tool.
Plain HTTP tool wrapper
Alternatively, install requests with pip install requests and register this wrapper. It sends POST https://keepbal.com/apis/v1/exa/contents with the direct JSON body, without the MCP input envelope. Choose either this wrapper or the MCP tools for the example.
import os
import requests
from langchain.tools import tool
@tool
def fetch_page(url: str) -> dict:
"""Fetch page contents through KeepBal, billed per successful call."""
response = requests.post(
"https://keepbal.com/apis/v1/exa/contents",
headers={"Authorization": f"Bearer {os.environ['KEEPBAL_API_KEY']}"},
json={"urls": [url], "text": True},
timeout=60,
)
response.raise_for_status()
return response.json()
from langchain.agents import create_agent
agent = create_agent("openai:gpt-4.1", tools=[fetch_page])
result = agent.invoke({"messages": [{"role": "user", "content": "Fetch https://example.com and summarize it."}]})
print(result)
Troubleshooting
Initialization and tools/list work without a key; every tools/call requires a valid bearer key, including search and inspect. For 401 check the key and client launch environment. For insufficient_credits check Wallet; for rate_limited respect Retry-After. Check Usage after uncertain outcomes before retrying a paid call. Truncated or unsupported MCP results must not be retried.
Exa contents tool · Search and extraction tools · Errors · MCP reference · All integrations