Skip to main content
Glama
de-snake

front-asset-intel-mcp

by de-snake
README.md
# front-asset-intel-mcp

Lightweight local TypeScript MCP server exposing **precomputed** asset research and rubric summaries for analyst agents.

This repo is intentionally runtime-small: the MCP server does not call an LLM, crawl the web, or regenerate research. It only serves validated local files.

## Research workflow for new assets

The copied research workflow lives in [`docs/asset-investment-diligence/`](docs/asset-investment-diligence/). Start with [`docs/asset-investment-diligence/RUN-RESEARCH.md`](docs/asset-investment-diligence/RUN-RESEARCH.md) when producing a new token or PT package.

New research is generated as an offline artifact first, normally under `research-runs/<run-slug>/`, not directly under `data/assets/`. For MCP-quality packages, run S1/S2 token diligence, include S4/S5 X/social research and S6 quantitative return context, and run S3 only when the asset is a Pendle PT / PT market. After review, import the curated result into `data/assets/<asset-slug>/{manifest.json,summary.asset_risk_v1.json,research.md}` and run `npm test`.

## Why this exists

Long Markdown research reports are useful for diligence, but they are not a stable decision interface for an analyst agent. The server exposes a small discovery surface plus two data layers:

- `list_available_assets` — discovery JSON listing every static asset this MCP can answer about, accepted lookup values, and exact examples for calling summary/research when the agent already knows a symbol or address.
- `get_asset_summary` — compact rubric JSON with uniform questions, fixed scoring buckets, table-facing `agent_display` fields, per-rubric score/status/evidence-state fields, evidence snippets, blocking unknowns, per-topic comparable grade anchors, and a normalized `return_context` that carries the full local return/social/quant overlay.
- `get_asset_research` — full Markdown report for source review when the summary needs expansion, with the same `return_context` inline so the research view and JSON view use the same ROI layer.

## Tools

### `list_available_assets`

No input. Returns a static asset-capability map with:

- available asset count;
- each asset's canonical `asset_id`, slug, symbol, chain, addresses, aliases, and accepted lookup values;
- recommended `get_asset_summary` / `get_asset_research` examples for symbol-first, token-address-first, Pendle-market-address-first, and PT-address-first callers.

Use this when an agent is unsure which identifiers the MCP recognizes or needs a deterministic way to call the summary/research tools without web discovery.

### `get_asset_summary`

Input accepts any one of:

- `asset_id`
- `symbol`
- slug / alias / token address / Pendle market address / PT address / chain-prefixed address

Returns precomputed JSON enriched with static rubric grade anchors from `data/rubrics/asset_risk_v1.json` and a runtime-built `return_context` from the same local summary/report package.

For table/ranking UIs, use the `agent_display` block first:

- `agent_display.score_display` — explains whether the table score is direct asset-quality evidence or fixed-return PT economics with inherited underlying risk shown separately.
- `agent_display.decision_label` — human-usable action label such as "Block Preview/Execute", "Conditional PT candidate", or "Do not underwrite" instead of the legacy coarse `review_required` bucket.
- `agent_display.underwriting_status` and `agent_display.execution_automation_status` — separate research/underwriting readiness from automation safety.
- `agent_display.primary_blockers` and `agent_display.next_action` — the concrete reason the row is not executable and what input is needed next.

`rubric.score` / `rubric.decision_class` remain for backward compatibility and deterministic score validation. Do not use those two fields alone as the table decision: PT rows expose a separate fixed-return table score, and `review_required` is only a legacy score-bucket class.

For analyst-agent scoring helper use, read `dimensions[]` as the main surface. Each dimension includes the current asset answer/score plus `possible_grades`: every fixed rubric bucket with condition, score range, score band, default status/evidence state, `is_selected`, and `relation_to_selected`. This lets an agent see, for example, that daily NAV attestations without granular reconciliation sit between weak monthly/no-granularity evidence and strong realtime/daily granular backing portfolio reporting.

For ROI/ranking use, read `return_context` as the normalized layer shared by both tools:

- `kind: direct_or_variable_token_return` for non-PT/direct token rows. It carries `token_return_estimate` with organic/variable ROI, fresh-farming points ROI where quantitatively modeled, expected-loss scenarios, exit cost, and risk-adjusted ROI/annualized return.
- `kind: fixed_maturity_pt_return` for Pendle PT rows. It carries `pt_return_profile` with gross ROI, APY/APR, expected-loss and exit-cost assumptions, break-even drawdown, liquidity, and risk-adjusted ROI/annualized return. Variable yield/incentive economics are explicitly separated into YT and are not counted in the PT-holder base ROI.
- Both kinds carry `social_research_layer` and `quantitative_risk_return_layer` when available, including X/social evidence and quantitative decision triggers.

For non-PT/simple-token rows, summaries also expose `simple_token_return_estimate` at the top level and mirrored in `agent_display.simple_token_return_estimate`, plus a compact `agent_display.simple_token_return_display`. These estimates separate: organic return from holding the token (`organic_yield_apy_estimate`, `organic_roi_over_horizon`), quantitatively backed fresh-farming points value (`estimated_points_roi_over_horizon`, `estimated_points_annualized_return`, `points_roi_scenarios_over_horizon`, `points_farming_thesis`), expected-loss scenarios (`expected_loss_prior`, `expected_loss_prior_scenarios`), exit cost, and risk-adjusted ROI before/after the base points case.

The normalized base formula is `risk_adjusted_roi_after_base_points = organic_roi_over_horizon + estimated_points_roi_over_horizon - expected_loss_prior - exit_cost_assumption`, then annualized linearly over `horizon_days` for table comparability. `expected_loss_prior_scenarios` keeps low/base/high loss cases so a conservative stress haircut is not mistaken for the only average estimate; `risk_adjusted_roi_scenarios_after_base_points` recomputes the same formula under the low-loss/base/high-loss loss cases.

Points are not shown as cheap safe floors. For points programs, `points_farming_thesis.kind = fresh_quant_farming_thesis` and the estimate must name program allocation, season timing, route multiplier, FDV scenarios, raw TVL proxy, weighted points-denominator scenarios, formula, freshness limits, and evidence. Where no confirmed points program exists, `points_thesis_kind = no_confirmed_points_program` and points ROI is `0`, not omitted.

Example asset lookups:

- `apxUSD`
- `apyUSD`
- `PRIME`
- `deSPXA`
- `USDC`
- `USDat`
- `sUSDat`
- `PT-apxUSD`
- `PT-apyUSD`
- `PT-USDat`
- `PT-sUSDat`
- `ethereum:0x98a878b1cd98131b271883b390f68d2c90674665`
- `0xaf0349fb9b1ba07d34381870c59b560b31412660`
- `0x30bb9ee8dc6aab322dc3a0d36063cbf06a9e5952`
- `0x9afe7a057a09cf5da748d952078c9c99938b4329`
- `0x91bc86899c8391b6caaf26535b9cd82efe49a189`

### `get_asset_research`

Same lookup input. Returns the full Markdown research report with the same normalized `return_context` used by `get_asset_summary` carried inline for auditability. This is not a separate shortcut estimate: both tools expose the same local return layer derived from the saved summary/report package.

For non-PT/direct token rows, the context is `direct_or_variable_token_return` and includes organic/variable ROI, fresh-farming points ROI when quantitatively modeled, expected-loss low/base/high bands, exit cost, risk-adjusted ROI, and social/X plus quantitative overlays. For PT rows, the context is `fixed_maturity_pt_return` and includes the PT fixed-return `return_profile`; PT research keeps `simple_token_return_estimate` unset and does not add token-points assumptions because PT variable yield/incentive economics are separated into YT.

## Seed assets

- `ethereum-apxusd` — Apyx apxUSD token-level research and `asset_risk_v1` summary, refreshed from the public rich report package.
- `ethereum-pendle-pt-apxusd-2026-11-05` — Pendle PT apxUSD 05 Nov 2026 research and summary with fixed-return risk-adjusted APY / hurdle overlay.
- `ethereum-apyusd` — Apyx apyUSD public research package, including X/social and quantitative risk/return layers.
- `ethereum-pendle-pt-apyusd-2026-08-27` — Pendle PT apyUSD 27 Aug 2026 report and summary, including the 83-day fixed-return recovery trade overlay.
- `ethereum-prime` — Hastra PRIME rich public report package normalized into the asset-quality rubric.
- `base-despxa` — Centrifuge deSPXA rich public report package normalized into the asset-quality rubric.
- `ethereum-usdc` — Circle USDC known-asset package with top-tier stablecoin/backing, tested-peg, issuer-control, and no-points direct-token return context.
- `ethereum-usdat` — Saturn USDat collateral package with Gearbox feed/oracle context, X/social layer, and public asset reports.
- `ethereum-susdat` — Saturn sUSDat collateral package with ERC-4626/feed context, X/social layer, and public asset reports.
- `ethereum-pendle-pt-usdat-2026-08-27` — Pendle PT USDat 27 Aug 2026 PT market dossier plus quantitative fixed-return hurdle overlay.
- `ethereum-pendle-pt-susdat-2026-08-27` — Pendle PT sUSDat 27 Aug 2026 PT market dossier plus quantitative fixed-return hurdle overlay.

PT markets reuse the underlying asset-risk rubric for inherited issuer/backing/control context, but table ranking uses PT-specific fixed-return economics. The PT adds a `return_profile` block plus optional `social_research_layer` and `quantitative_risk_return_layer` blocks: maturity, PT price, accounting-asset price, gross ROI, annualized return, expected-loss prior, risk-adjusted return after expected loss/exit cost, break-even drawdown, and liquidity snapshot. PT holders underwrite the fixed discount-to-maturity; variable yield is separated into YT and not part of the PT-holder return.

## Data layout

```text
data/
  rubrics/
    asset_risk_v1.json
  assets/
    <asset-slug>/
      manifest.json
      summary.asset_risk_v1.json
      research.md
src/
  server.ts
  registry.ts
  validate-data.ts
  smoke.ts
```

## Rubric model

`asset_risk_v1` totals 100 points:

- Backing / NAV evidence: 18
- Redemption and holder eligibility: 18
- Market liquidity and peg behavior: 18
- Issuer controls and governance: 14
- Oracle / accounting alignment: 10
- Audits and security review: 12
- Incidents and social stress: 10

Each dimension has fixed answer buckets and score ranges. Summaries store the selected bucket, score, `score_band`, dimension-level action `status`, `evidence_state`, evidence, confidence, blocking unknowns, and — where available — `social_research_layer` / `quantitative_risk_return_layer` overlays that expose fixed-return APY, hurdle, expected-loss, and risk-adjusted-return information without folding those economics into the 100-point asset-quality score.

Dimension `status` values are action-oriented:

- `usable_for_review` — this dimension has usable evidence and does not itself force a review gate.
- `review_required` — evidence is partial, stale, or size/holder-specific enough that an analyst must review it.
- `block_automation` — the dimension can be discussed, but automated Preview/Execute should not proceed until the missing input is resolved.
- `cannot_underwrite` — the dimension contains a material valuation/risk gap or negative evidence that prevents underwriting under current assumptions.

`score_band` is the scoring bucket quality (`strong`, `partial`, `weak`). `evidence_state` preserves whether the status came from verified support, partial support, source inconclusiveness, missing/unknown evidence, or negative evidence.

## Install and verify

```bash
npm install
npm test
```

`npm test` runs:

1. TypeScript build.
2. Data validation against manifests/rubric schema.
3. Registry smoke lookups for `list_available_assets`, apxUSD, apyUSD, PRIME, deSPXA, USDat, sUSDat, and PT assets, including a chain-prefixed market-address lookup.
4. Real MCP stdio smoke test:
   - initializes the MCP server;
   - checks `tools/list` exposes `list_available_assets`, `get_asset_summary`, and `get_asset_research`;
   - calls `list_available_assets` and verifies symbol/address call guidance plus accepted lookup values;
   - calls `get_asset_summary` for APYx, Saturn, PRIME, and deSPXA assets;
   - calls `get_asset_summary` by a chain-prefixed PT market address to verify address-first callers can use the guidance;
   - verifies PT fixed-return table scores and risk-adjusted APY values for `PT-apxUSD`, `PT-apyUSD`, `PT-USDat`, and `PT-sUSDat`;
   - calls `get_asset_research` for all direct/variable-token reports and verifies the inline normalized return context mirrors the summary ROI basis (organic/variable ROI, fresh-farming points ROI, risk-adjusted ROI, and social/X context);
   - calls `get_asset_research` for PT reports and verifies the fixed-return risk-adjusted conclusions are present without simple-token points assumptions.

For only the MCP protocol smoke after a build:

```bash
npm run build
npm run smoke:mcp
```

## Run as local MCP server

```bash
npm run build
node dist/server.js
```

Example MCP client command config:

```json
{
  "mcpServers": {
    "front-asset-intel": {
      "command": "node",
      "args": ["/absolute/path/to/front-asset-intel-mcp/dist/server.js"]
    }
  }
}
```

From this workspace, the absolute command target is:

```text
/Users/ilya/ai-assistant/projects/front-asset-intel-mcp/dist/server.js
```

## Source lineage

Seed reports were copied or condensed from the public Front KB rich-report branch (`de-snake/front-knowledge-base`, commit `b954049`). The MCP evidence surface is local: `data/assets/<asset-slug>/research.md` plus `summary.asset_risk_v1.json`.

Summaries preserve coarse `generated_from` provenance, but manifest and summary evidence pointers intentionally point to local files or public URLs, not invisible upstream run paths.

TDQS

A3.9/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct purposes: one returns a detailed Markdown research report, the other returns a rubric-style JSON summary. There is no overlap in their outputs or intended use cases.

Naming Consistency5/5

Both tools follow a consistent 'get_asset_<noun>' pattern, using the same verb 'get' and clearly differentiating the resource object ('research' vs 'summary').

Tool Count2/5

With only two tools, the server feels under-scoped for an asset intelligence platform. Users likely need additional capabilities like searching, listing, or comparing assets, which are absent.

Completeness2/5

The tool set covers retrieval of two specific asset reports but lacks any CRUD operations, listing, search, or ability to handle multiple assets. This represents significant gaps in functionality for a dedicated asset intelligence server.

Maintenance

ActivityInactive
ResponsivenessNo issues