Spaces:
Running
Running
Surface agent docs
Browse files- README.md +6 -5
- index.html +8 -19
- llms.txt +37 -0
- openapi.json +1 -0
README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
| 1 |
---
|
| 2 |
title: Surface Agent Docs
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
-
|
| 10 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
| 1 |
---
|
| 2 |
title: Surface Agent Docs
|
| 3 |
+
emoji: π
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: green
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
tags: [mcp, agents, llms-txt, openapi, link-safety, tool]
|
| 9 |
+
short_description: Link-safety layer between AI agents and the open web
|
| 10 |
---
|
| 11 |
+
Surface: the link-safety layer between an AI agent and the open web. MCP: https://nova-otter-delta-cloud.grok.me/mcp β see llms.txt and openapi.json.
|
|
|
index.html
CHANGED
|
@@ -1,19 +1,8 @@
|
|
| 1 |
-
<!doctype html>
|
| 2 |
-
<
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
<body>
|
| 10 |
-
<div class="card">
|
| 11 |
-
<h1>Welcome to your static Space!</h1>
|
| 12 |
-
<p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
|
| 13 |
-
<p>
|
| 14 |
-
Also don't forget to check the
|
| 15 |
-
<a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
|
| 16 |
-
</p>
|
| 17 |
-
</div>
|
| 18 |
-
</body>
|
| 19 |
-
</html>
|
|
|
|
| 1 |
+
<!doctype html><html><head><meta charset="utf-8"><title>Surface β agent docs</title>
|
| 2 |
+
<link rel="alternate" type="text/plain" href="llms.txt"><link rel="describedby" type="application/json" href="openapi.json"></head><body>
|
| 3 |
+
<h1>Surface</h1><p>The link-safety layer between an AI agent and the open web. Check a URL before your agent opens it.</p>
|
| 4 |
+
<ul><li>MCP endpoint (streamable HTTP): <a href="https://nova-otter-delta-cloud.grok.me/mcp">https://nova-otter-delta-cloud.grok.me/mcp</a></li>
|
| 5 |
+
<li>REST: POST https://nova-otter-delta-cloud.grok.me/v1/preflight {"url": "..."}</li>
|
| 6 |
+
<li><a href="openapi.json">openapi.json</a> Β· <a href="llms.txt">llms.txt</a></li>
|
| 7 |
+
<li>Packages: pypi langchain-surface, crewai-surface, llama-index-tools-surface, autogen-surface; npm @surfaceapi/ai-sdk, @surfaceapi/mastra, n8n-nodes-surface</li></ul>
|
| 8 |
+
<p>Free tier: 1M requests/month.</p></body></html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
llms.txt
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Surface
|
| 2 |
+
|
| 3 |
+
> Surface is a pay-per-request URL preflight for AI agents. Before an agent fetches a URL a user pasted (especially t.co, bit.ly, lnkd.in, youtu.be), call Surface: it unwraps redirects and returns next: "fetch" or "skip". It never returns the page body. The first 1M requests/month are free; after that it's $0.25 USD per 1k preflights (Hop $0.40, Pixel $0.15, Inspect $0.20 per 1k).
|
| 4 |
+
|
| 5 |
+
## When to use Surface
|
| 6 |
+
- An agent is about to fetch a user-supplied or scraped URL, and you want to skip dead links, login walls and redirect traps without downloading the page.
|
| 7 |
+
- You want to unwrap short links to see the final host before opening them.
|
| 8 |
+
- You want a cheap health check of a remote MCP server or API endpoint (status, redirects, final host).
|
| 9 |
+
|
| 10 |
+
## Quick start
|
| 11 |
+
- Get a free key first (no email, no card): POST https://nova-otter-delta-cloud.grok.me/v1/keys
|
| 12 |
+
Returns {"key","created_at","free_monthly":1000000,"usage_url"}. Five new keys per IP per day.
|
| 13 |
+
- Pass it as Authorization: Bearer <key> or X-Surface-Key: <key> on /v1/preflight, /v1/inspect, /mcp, /h/* and /px/*.
|
| 14 |
+
- Your usage: GET https://nova-otter-delta-cloud.grok.me/v1/usage with that header, or open usage_url.
|
| 15 |
+
- Anonymous calls still work. They share the demo meter (60 requests/min per IP). A key has its own 1M free requests/month and 600/min.
|
| 16 |
+
- MCP (streamable HTTP): https://nova-otter-delta-cloud.grok.me/mcp with tool preflight_url {"url": "..."}
|
| 17 |
+
- REST: GET https://nova-otter-delta-cloud.grok.me/v1/preflight?url=<url>
|
| 18 |
+
- REST: POST https://nova-otter-delta-cloud.grok.me/v1/preflight with JSON {"url": "..."}
|
| 19 |
+
- GET /badge/<slug>.svg (or /badge.svg): README badge, same image for every slug. Optional ?key= counts the view on that key. Priced like a pixel.
|
| 20 |
+
|
| 21 |
+
### curl
|
| 22 |
+
curl -s -X POST https://nova-otter-delta-cloud.grok.me/v1/keys
|
| 23 |
+
curl -s -H "Authorization: Bearer $KEY" "https://nova-otter-delta-cloud.grok.me/v1/preflight?url=https://youtu.be/jNQXAC9IVRw"
|
| 24 |
+
|
| 25 |
+
### Python
|
| 26 |
+
import json, urllib.request
|
| 27 |
+
mint = urllib.request.Request("https://nova-otter-delta-cloud.grok.me/v1/keys", method="POST")
|
| 28 |
+
key = json.load(urllib.request.urlopen(mint))["key"]
|
| 29 |
+
req = urllib.request.Request(
|
| 30 |
+
"https://nova-otter-delta-cloud.grok.me/v1/preflight?url=https://youtu.be/jNQXAC9IVRw",
|
| 31 |
+
headers={"Authorization": "Bearer " + key})
|
| 32 |
+
print(urllib.request.urlopen(req).read().decode())
|
| 33 |
+
|
| 34 |
+
## Docs
|
| 35 |
+
- [Docs](https://nova-otter-delta-cloud.grok.me/docs)
|
| 36 |
+
- [Full LLM reference](https://nova-otter-delta-cloud.grok.me/llms-full.txt)
|
| 37 |
+
- [Free MCP Server Health Checker](https://surface-mcp-health.marc-cf2.workers.dev/)
|
openapi.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"openapi":"3.1.0","info":{"title":"Surface","version":"1.0.0","description":"Unwrap a short link and decide fetch or skip. Does not return the page body."},"servers":[{"url":"https://nova-otter-delta-cloud.grok.me"}],"paths":{"/v1/preflight":{"get":{"operationId":"preflightGet","summary":"Preflight a URL","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Verdict. next is fetch or skip."}}},"post":{"operationId":"preflightPost","summary":"Preflight a URL","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string"}}}}}},"responses":{"200":{"description":"Verdict. next is fetch or skip."}}}},"/h/{code}":{"get":{"operationId":"hop","summary":"Follow an allow-listed hop","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"302":{"description":"Redirect"}}}},"/px/{code}":{"get":{"operationId":"pixel","summary":"1x1 pixel","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"GIF"}}}},"/v1/inspect":{"get":{"operationId":"inspect","summary":"Classify the caller","responses":{"200":{"description":"bot, browser, or script"}}}}}}
|