Skip to main content
Glama
README.md
# Athena Agent — live earthquake feed

An Athena AI agent backed by an MCP server. It pulls real seismic readings from the
USGS public feed and renders them in an interactive widget inside the chat.

## Run it

```bash
npm install
npm start          # http://localhost:8787/mcp
```

Verify before touching Athena:

```bash
npx @modelcontextprotocol/inspector@latest --server-url http://localhost:8787/mcp --transport http
```

You should see one tool, `get_recent_earthquakes`, and one resource,
`ui://widget/quakes.html`, with mimeType `text/html+skybridge`.

## Expose over HTTPS

Athena requires HTTPS. For development:

```bash
ngrok http 8787
```

Register the agent at <https://athenachat.bot/chatbot/mybots/create> and set the MCP
URL to `https://<your-subdomain>.ngrok.app/mcp` — the `/mcp` path is required.

For a URL that survives past the demo, push this repo and deploy to Render or
Railway. Build command `npm install`, start command `npm start`. Both inject `PORT`,
which the server reads.

## Prompts that trigger the tool

- "Show me recent earthquakes"
- "Has there been any seismic activity today?"
- "Any big quakes in the past week?"

## What makes the widget interactive

| Control | Behaviour |
| --- | --- |
| Magnitude slider | Filters instantly in the browser, no server call |
| Row click | Expands depth, coordinates, tsunami flag |
| Time window buttons | Calls `get_recent_earthquakes` again via `window.openai.callTool` and re-renders with fresh data |

State survives re-render through `window.openai.setWidgetState`.

## Adapting this to another data source

Two places change, both marked in the code.

1. `server.js` — the `fetchData` function. Return `{ items: [...], meta: {...} }`.
   Also update the tool name, description, and `inputSchema` to match the new domain.
2. `public/widget.html` — the `render` function, and the two control handlers.

Everything else (transport, resource registration, CORS, metadata) is domain-agnostic.

## Things that will waste your time

- `window.openai` is undefined → the resource mimeType is not exactly
  `text/html+skybridge`.
- `callTool` does nothing → the tool is missing `_meta["openai/widgetAccessible"]: true`.
- Widget can't fetch an API directly → the iframe CSP blocks it. Fetch server-side.
- Athena still shows old tools → Settings → Connectors → Refresh.
- Athena's docs import `@modelcontextprotocol/sdk/server/streamable-http.js`. That
  path does not exist. It is `streamableHttp.js`.