Plug measured web data
into what you already use.
Outrings is a keyless HTTP endpoint and a native MCP server. That makes the integration a URL in almost every case — no credential to store, no SDK to install, no account to provision.
Two ways in
Model Context Protocol
The client discovers eight tools, each with a description telling the model when to reach for it. You write no glue and decide nothing about when to call — the model does.
Use when: your client supports MCP. Claude, OpenAI Agents, Gemini CLI, Cursor, n8n and a growing list do.
https://outrings.com/mcp
Keyless REST
One GET returns JSON. GET and POST behave identically, CORS is open, and there is nothing to authenticate — so it works in any framework, any automation platform, and in a browser.
Use when: anything else. This route never stops working when an SDK changes shape.
GET https://outrings.com/api/v1/summary?url=example.com
Find your platform
| Platform | Route | How |
|---|---|---|
| MCP clients | Native | Any client speaking the Model Context Protocol |
| Claude | Native | Claude Code, Claude Desktop, or the Messages API |
| OpenAI Agents | Native | Agents SDK via MCP, or a plain function tool |
| Gemini | Native | Gemini CLI via MCP, or function calling |
| LangChain | Adapter | MCP adapter, or a one-function tool |
| LlamaIndex | Adapter | MCP tool spec, or a FunctionTool |
| n8n | No code | MCP client node, or an HTTP Request node |
| Zapier | No code | Webhooks by Zapier, GET |
| Make | No code | HTTP module, Make a request |
| Browser agents | Direct | Open CORS, no key to expose |
Any MCP client
The generic case. A client that speaks streamable HTTP MCP needs the endpoint and nothing else — no key, no stdio wrapper to install, no process to keep alive.
{
"mcpServers": {
"outrings": {
"type": "http",
"url": "https://outrings.com/mcp"
}
}
}
Verify before you trust it:
curl -X POST https://outrings.com/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Eight tools should come back. A GET on the same URL returns a plain description of the
server rather than an error, so a client probing the endpoint learns something either way.
Claude
Native MCP support in Claude Code and Claude Desktop, and ordinary tool use through the Messages API.
claude mcp add --transport http outrings https://outrings.com/mcp # Confirm it registered claude mcp list
OpenAI Agents
The Agents SDK can attach an MCP server directly, so the tools are discovered rather than declared. If you would rather not depend on that, a plain function tool is four lines of handler.
import asyncio
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp
async def main():
async with MCPServerStreamableHttp(
name="outrings",
params={"url": "https://outrings.com/mcp"},
) as outrings:
agent = Agent(
name="Site analyst",
instructions=(
"When asked about a specific website, measure it with the Outrings "
"tools rather than inferring from prior knowledge. Always report what "
"the result says was not checked."
),
mcp_servers=[outrings],
)
result = await Runner.run(agent, "Is example.com secure? Cite the evidence.")
print(result.final_output)
asyncio.run(main())Gemini
Gemini CLI reads an MCP server configuration. Through the API, the Google Gen AI SDK will call a plain Python function for you when you pass it as a tool.
# Add to your Gemini CLI settings file, then restart.
{
"mcpServers": {
"outrings": {
"httpUrl": "https://outrings.com/mcp"
}
}
}LangChain
The MCP adapter turns the whole server into LangChain tools in one call. For a single tool with no
extra dependency, the @tool decorator is enough.
# pip install langchain-mcp-adapters
import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient
async def main():
client = MultiServerMCPClient({
"outrings": {
"url": "https://outrings.com/mcp",
"transport": "streamable_http",
}
})
tools = await client.get_tools()
# `tools` are ordinary LangChain tools now — pass them to whichever
# agent constructor your version uses.
for t in tools:
print(t.name)
asyncio.run(main())LlamaIndex
The MCP tool spec exposes the server as a tool list. Otherwise a FunctionTool wraps the
same HTTP call.
# pip install llama-index-tools-mcp
import asyncio
from llama_index.tools.mcp import BasicMCPClient, McpToolSpec
async def main():
client = BasicMCPClient("https://outrings.com/mcp")
spec = McpToolSpec(client=client)
tools = await spec.to_tool_list_async()
for t in tools:
print(t.metadata.name)
# Hand `tools` to your agent as usual.
asyncio.run(main())n8n
Two routes. The MCP client node connects an n8n AI agent to the whole tool set; the HTTP Request node is the deterministic option for a scheduled workflow that always does the same thing.
As an agent tool
- Add an MCP Client Tool node and connect it to your AI Agent node's tool input.
- Set the endpoint to
https://outrings.com/mcpand the transport to HTTP Streamable. - Leave authentication as None — there is no key.
As a scheduled check
- Schedule Trigger — daily is a sensible default.
- HTTP Request — method
GET, URL as below. Response format JSON. - IF — branch on the value you care about.
- Slack / Email / Webhook — notify only on the failing branch.
https://outrings.com/api/v1/changes?url=example.com
Then branch on a regression rather than on an absolute score, so the workflow is quiet until something actually moves:
// IF node, expression mode — true when a check newly failed
{{ $json.comparable && $json.newProblems.some(p => p.status === 'fail') }}
A useful message body for the alert step:
{{ $json.newProblems.map(p => p.id).join(', ') }} — score {{ $json.scoreDelta }}
Zapier
No custom app and no credential, because there is nothing to authenticate.
- Trigger: Schedule by Zapier, or whatever starts your workflow.
- Action: Webhooks by Zapier → GET.
- URL:
https://outrings.com/api/v1/summary - Query String Params: key
url, valueexample.com— or map it from a previous step to check a different site each run. - Later steps can reference the parsed response fields directly, for example
score,verdictandgrade.
priorityActions 1 title. For anything more than a couple of fields, a
Code by Zapier step is easier to reason about than a long chain of pickers.// Code by Zapier — JavaScript
const response = await fetch(
'https://outrings.com/api/v1/summary?url=' + encodeURIComponent(inputData.site)
);
const result = await response.json();
return {
score: result.score,
verdict: result.verdict,
topFix: result.priorityActions[0]?.action ?? 'nothing outstanding',
notChecked: result.notCovered.join('; '),
};
Make
- Add an HTTP module → Make a request.
- URL:
https://outrings.com/api/v1/summary?url=example.com - Method
GET. No authentication. - Tick Parse response so the JSON becomes mappable fields.
- Add a Router or filter on
score, or on the length ofnewProblemsif you are using the changes endpoint.
A filter condition that only continues when something regressed:
{{ length(1.newProblems) }} > 0
If you would rather not tick Parse response, add a JSON → Parse JSON module afterwards and point it at the HTTP module's data.
Browser agents and extensions
Browser-side callers are first-class here: Access-Control-Allow-Origin is a wildcard,
the allowed methods are GET, POST, OPTIONS, and there is no key that could leak from
client-side code — because there is no key.
// Runs anywhere: content script, extension background worker, devtools panel,
// or a plain page. No proxy needed and nothing to keep secret.
const inspect = async (url, category = 'summary') => {
const response = await fetch(
`https://outrings.com/api/v1/${category}?url=${encodeURIComponent(url)}`
);
if (!response.ok) throw new Error(`Outrings responded ${response.status}`);
return response.json();
};
const result = await inspect(location.hostname, 'security');
console.log(result.score, result.problems.map(p => p.title));
For a browser agent that navigates and acts, the useful pattern is to measure the page it has landed on and feed the result back as context — so its next decision is made against headers and transport it cannot otherwise see.
What comes back, whichever route you take
Every response is built from the same four parts. The last two are what stop an agent, or a workflow, over-claiming from the result.
Findings
problems lists every failing check in check order.
priorityActions is the same set ranked by points recovered per unit of effort.
Evidence
Each finding carries found — the header value, certificate field or directive the
verdict came from — so the reason can be quoted rather than the conclusion.
Coverage
notCovered names what this service never measures, so an absent finding is not read
as a clean result.
Undetermined
undetermined holds checks that reached no verdict, with a reason —
blocked, timeout, requires_browser. Never scored.
Practical notes
- No key, no account. Nothing to provision, rotate or store in a platform's credential vault.
- Pick the smallest endpoint.
/scoreis around 1.7 KB, a single category two to eight,/summaryabout 8.5. A full report is around 124 KB, which is more than most workflow steps need. - Rate limits. 40 audits per hour and 200 per day per client. Repeating a URL within ten minutes is served from cache and does not consume quota.
- Timing. One to eight seconds. Set platform timeouts to 30 seconds or more — several no-code tools default to less.
- Errors are JSON. Non-2xx responses return
{"ok": false, "error": "…"}. Unreachable targets give 502, private addresses 403, rate limiting 429 withRetry-After. - Add
&refresh=1after a deploy. Otherwise a check running immediately afterwards may be served the cached previous result and pass.
Questions
Which route should I choose?
If your client speaks MCP, use it — the tools arrive already described and the model decides when to call them, which is less work and produces better-targeted calls. For everything else, or for a workflow that should do exactly the same thing on every run, use the REST endpoint.
Is there an official SDK?
Deliberately not. One keyless GET returning JSON does not need a dependency, and a package would be one more thing to version, publish and keep in step with the API. The OpenAPI specification is published if you would rather generate a client.
Can I run this against sites I do not own?
Yes. It sends ordinary HTTP requests and reads publicly served responses, exactly as a browser does — it is not a vulnerability scanner and does not probe or attempt authentication. Pace bulk runs considerately; each audit makes dozens of requests to the site being measured. More on where the line is.
My platform is not listed. Now what?
If it can make an HTTP request, it is supported. There is no authentication step, no signing, no header requirement and no SDK — the integration is the URL. The API documentation has the full endpoint list and response shaping options.
See the data before you wire it up
Run an inspection in the browser — it is the same result every integration above returns, rendered.
Outrings for AI agents · API documentation · OpenAPI · llms.txt