Skip to content

Repository files navigation

foc-observer

Observability tools for FOC (Filecoin Onchain Cloud).

Provides AI agents and humans with access to:

  • Indexed event history from all FOC contracts (SQL)
  • Live contract state via Lotus RPC (providers, datasets, payment rails, pricing)
  • DealBot quality metrics (deal success, IPFS retrieval, provider health)
  • Proving health from the PDP Explorer subgraph (fault rates, weekly trends)

Public API endpoint URL isn't shared here, you'll either need to run your own from this repo or ask for an official endpoint that's actively indexing.

Quick Start

Remote MCP (zero install, recommended)

Any MCP client that supports Streamable HTTP transport can connect directly, no npm install needed:

https://your-server.example.com/mcp

20 tools with embedded FOC protocol knowledge.

Claude Code (streamable HTTP):

# Project-local (default)
claude mcp add --transport http foc-observer https://your-server.example.com/mcp
# Shared with all projects
claude mcp add --transport http --scope user foc-observer https://your-server.example.com/mcp

Claude.ai: Add as a connector in Settings > Connectors with the /mcp URL.

Stdio MCP (via npm package)

For MCP clients that only support stdio transport:

npx @filoz/foc-observer serve --api-url https://your-server.example.com

Claude Code (stdio):

claude mcp add --transport stdio foc-observer -- npx @filoz/foc-observer serve --api-url https://your-server.example.com

Claude Desktop / Cursor / other MCP hosts, add to your MCP config (e.g. claude_desktop_config.json):

{
"mcpServers": {
"foc-observer": {
"command": "npx",
"args": ["@filoz/foc-observer", "serve", "--api-url", "https://your-server.example.com"]
}
}
}

Scope (Claude Code)

  • --scope local (default): available only to you in the current project
  • --scope project: shared with everyone via .mcp.json (checked into repo)
  • --scope user: available to you across all projects

Other MCP clients

Works with any MCP-compatible client; Cursor, Cline, Gemini CLI, Amazon Q, goose, ChatGPT, JetBrains AI, LM Studio, and many more. Use the HTTP endpoint for clients that support Streamable HTTP, or the stdio proxy via npx @filoz/foc-observer serve for the rest. See the client package README for a compatibility table.

REST API

All data is available via a public REST API with CORS enabled:

# Network status
curl https://your-server.example.com/status
# SQL query against indexed events
curl -X POST https://your-server.example.com/sql \
-H "Content-Type: application/json" \
-d '{"network":"mainnet","sql":"SELECT provider_id, COUNT(*) as datasets FROM fwss_data_set_created GROUP BY provider_id"}'# Live contract state
curl https://your-server.example.com/providers/mainnet
curl https://your-server.example.com/dataset/mainnet/100
curl https://your-server.example.com/rail/mainnet/100
# Proving health (from PDP Explorer subgraph)
curl https://your-server.example.com/proving/providers/mainnet
# DealBot quality metrics
curl https://your-server.example.com/metrics/providers/mainnet?hours=72

MCP Tools

20 tools across 5 data sources:

CategoryToolsSource
Knowledgeget_system_contextEmbedded protocol docs
Eventsquery_sql, list_tables, describe_table, get_statusPonder-indexed Postgres
Contract Stateget_providers, get_provider, get_dataset, get_dataset_proving, get_rail, get_pricing, get_account, get_auctionLotus RPC (eth_call)
Quality Metricsget_dealbot_stats, get_dealbot_providers, get_dealbot_provider_detail, get_dealbot_daily, get_dealbot_failuresBetterStack / DealBot API
Proving Healthget_proving_health, get_proving_datasetPDP Explorer subgraph (Goldsky)

Analytical tools require the agent to call get_system_context first and pass i_have_read_the_system_context: true to confirm it has loaded the protocol knowledge needed to interpret results correctly.

Self-Hosting

Prerequisites

  • Docker and Docker Compose
  • Filecoin Lotus nodes, or access to a public RPC like Glif, although for deep history an archival node will be required

Setup

# Clone
git clone https://github.com/your-org/foc-observer.git
cd foc-observer
# Create Docker volumes for Ponder data
docker volume create ponder_pgdata-calibnet
docker volume create ponder_pgdata-mainnet
# Configure
cp .env.example .env
# Edit .env with your RPC endpoints, public URL, etc.# Start
docker compose up -d

When upgrading to this unified configuration, rebuild the indexers before restarting them. The unified ponder.config.ts is baked into the indexer image, so mounting the updated source directories alone does not update it:

docker compose up -d --build ponder-calibnet ponder-mainnet

Configuration

All configuration is via .env. Copy .env.example for a template.

VariableRequiredDescription
FOC_API_URLYesPublic URL of your deployment
FOC_SERVER_PORTYesHTTP server port
CALIBNET_RPC_URLYesCalibnet Lotus RPC endpoint
MAINNET_RPC_URLYesMainnet Lotus RPC endpoint
LOTUS_CALIBNET_HOSTNoLocal Lotus host for socat proxy (default 127.0.0.1)
LOTUS_CALIBNET_PORTNoLocal Lotus port for socat proxy (default 2235)
LOTUS_MAINNET_HOSTNoLocal Lotus host for socat proxy (default 2234)
LOTUS_MAINNET_PORTNoLocal Lotus port for socat proxy (default 2234)
BETTERSTACK_CH_USERNoBetterStack ClickHouse username (enables DealBot metrics)
BETTERSTACK_CH_PASSWORDNoBetterStack ClickHouse password
CALIBNET_DATA_SCHEMANoActive Ponder data schema (default data_v1); bump on reindex
MAINNET_DATA_SCHEMANoActive Ponder data schema (default data_v1); bump on reindex

Using remote RPC (e.g. Glif):

Set CALIBNET_RPC_URL and MAINNET_RPC_URL to the remote endpoints and start without the proxy:

docker compose up -d postgres-calibnet postgres-mainnet ponder-calibnet ponder-mainnet foc-observer

Using local Lotus nodes:

The lotus-proxy container (the only one with host networking) forwards two specific ports from your host into the Docker bridge network. All other containers are network-isolated.

docker compose up -d

Architecture

Internet
--> nginx (TLS, rate limiting)
--> foc-observer container
Docker bridge network:
foc-observer --> postgres-calibnet, postgres-mainnet (indexed events)
--> ponder-calibnet, ponder-mainnet (indexers)
--> lotus-proxy (RPC, via bridge gateway)
Host network (lotus-proxy only):
socat :11234 --> Lotus mainnet gateway
socat :11235 --> Lotus calibnet gateway

Containers run as non-root (USER node). Only lotus-proxy has host networking, forwarding exactly two ports.

Re-indexing (zero-downtime schema changes)

Each Ponder indexer writes its tables to a named Postgres schema (CALIBNET_DATA_SCHEMA / MAINNET_DATA_SCHEMA in .env, default data_v1) and auto-creates views in public, which is all the server ever queries. Indexer schema or handler changes require a full re-index, done in parallel with zero query downtime:

  1. Define a temporary ponder-<network>-reindex service in a compose override file, running --schema data_vN (the next version, no --views-schema) against the same Postgres.
  2. Let it catch up. It shares Ponder's ponder_sync raw-chain cache, so code-only changes re-index from local data at high speed without re-fetching from RPC; only config changes (new contracts, earlier start blocks) need RPC.
  3. At cutover: stop the live indexer, drop and recreate the public schema, bump <NETWORK>_DATA_SCHEMA in .env, remove the reindex container, start the live indexer (it recreates the public views over the new schema), and restart foc-observer.
  4. Drop the old data_v* schema when satisfied.

Do not restart the live indexer containers while a reindex is catching up: they volume-mount the indexer source, and restarting them under changed code makes Ponder rebuild their current schema in place.

Client (@filoz/foc-observer)

cd client
npm install
npm run build
npm test

Server

cd server
npm install
npm run build
npm test

Indexer

The Ponder indexer uses a Filecoin-compatible fork of Ponder. Set PONDER_NETWORK to mainnet or calibnet; the default is mainnet for local development. Set PONDER_STRICT_ENV=true to require PONDER_NETWORK, DATABASE_URL, and RPC_URL, as the Docker Compose services do.

Useful commands:

cd indexer
npm run dev:mainnet
npm run dev:calibnet
npm run codegen:mainnet
npm run codegen:calibnet
npm test
npm run typecheck

To regenerate contract ABIs:

cd indexer
./scripts/generate-abis.sh # Uses the default ref pinned in the script
./scripts/generate-abis.sh main # Or specify a ref

The FilecoinWarmStorageService ABI is a union: the script folds in events declared in FWSS's internal libraries (emitted from the FWSS proxy but omitted from the published contract ABI by forge) plus legacy events retained for older deployments, so one ABI serves all deployed contract versions. See indexer/abis/fwss-extra-events.json.

What is FOC?

FOC (Filecoin Onchain Cloud) is a decentralized storage service built on Filecoin. Clients pay storage providers to store data, with payments and proofs of data possession managed entirely on-chain via smart contracts:

License

Apache-2.0 OR MIT

About

AI-centric observability tools for FOC (Filecoin Onchain Cloud)

Resources

Security policy

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages