Skip to main content
Glama
README.md
# assetlens

assetlens gives an agent read-only access to the public side of a
marketplace for real-world assets — agro and energy first, growing
into mining, equipment, and industrial services. It wraps the
platform's anonymous tier: no account, no token, and nothing that
writes. You can read the onboarding document, search marketplace
listings, search projects, run one unified search across both, and
fetch the full public document behind a search hit. One binary
serves a command-line interface and a stdio MCP server.

The upstream is a hosted MCP endpoint spoken to over JSON-RPC 2.0.
The anonymous tier is documented at 60 requests per minute per
client; this tool simply forwards each call, unwraps the result
envelope (the payload arrives as JSON inside the result's text
content, mirrored in structured content), and prints what came
back. Set `EPINU_MCP_URL` to point at a different endpoint; the
documented production endpoint is the default.

## Install

```bash
npx @reneturcios/assetlens search --query ASIC
```

Or run the container image:

```bash
docker run -i ghcr.io/cloudcorprecords/assetlens
```

The container defaults to the MCP server (see below); pass CLI
arguments to use it as a CLI instead.

## CLI

```bash
assetlens getting_started
assetlens marketplace_listings_search --query "ASIC repair"
assetlens marketplace_listings_search --category equipment --max-price 3000 --limit 5
assetlens projects_search --query mining
assetlens search --query ASIC
assetlens fetch --id listing:f7edbcad-ecbc-46d0-a8f6-162fc8219089

assetlens --version
```

Every command prints the upstream payload as JSON (the onboarding
document prints as text). Exit codes: `0` on success, `1` on a
runtime or upstream error, `2` for usage errors. Arguments are
validated before any network call: an undocumented category, a
missing or over-long query or id, or an unknown flag is a usage
error, never a network request.

Search arguments follow the platform's published tables exactly.
For `marketplace_listings_search` and `projects_search`, the
tables mark `maxPrice`, `limit`, and `cursor` optional and leave
`query` (and `category`) unmarked, so none of them are required
here. `search` requires `query` (1–200 characters) and `fetch`
requires `id` (1–120 characters). `category` accepts only `product`,
`service`, `repair_services`, `equipment`, or `energy`.

## What the tools return

- `marketplace_listings_search` returns `results` (listings with
  fields such as `listing_id`, `title`, `category`, `pricing_mode`,
  `price` — a number or `null` — `status`, and
  `location_address`), a `next_cursor` (`null` when there is no
  further page), and the `limit` used.
- `projects_search` returns `projects`, each with `project_id`,
  `name`, and `summary`.
- `search` is deliberately shallow: each hit carries only `id`,
  `title`, and `url`. The id is prefixed — `project:<uuid>` or
  `listing:<uuid>` — so you can tell which side of the platform a
  hit came from.
- `fetch` returns the full document for one id: `id`, `title`,
  `text`, `url`, and `metadata` (for a listing, its `type`,
  `category`, `pricing_mode`, `price`, `availability_type`, and
  `location_address`). An unknown or malformed id is an upstream
  tool error — `Resource not found.` with status code 404 — and
  assetlens surfaces it as an error rather than inventing a result.

## MCP server

One bin serves both faces. The `mcp` subcommand starts a stdio MCP
server:

```bash
npx -y @reneturcios/assetlens mcp
```

MCP client configuration:

```json
{
  "mcpServers": {
    "assetlens": {
      "command": "npx",
      "args": ["-y", "@reneturcios/assetlens", "mcp"]
    }
  }
}
```

### Tools

| Tool | Input | What it returns |
| --- | --- | --- |
| `getting_started` | (none) | The platform onboarding document for agents: operating model, auth tiers, common flows, and etiquette. |
| `marketplace_listings_search` | `query?`, `category?`, `maxPrice?`, `limit?`, `cursor?` | Public marketplace listings matching the filters, with a paging cursor. |
| `projects_search` | `query?`, `limit?`, `cursor?` | Public projects matching the query. |
| `search` | `query` (required, 1–200 chars) | Unified hits over projects and listings: `{id, title, url}` only. |
| `fetch` | `id` (required, 1–120 chars) | The full public document for one search hit. |

### What is not included

With a delegated token the same platform exposes more tools —
identity, proposal-creating writes, and proposal listing among
them (`whoami`, `marketplace_listing_create`, `project_create`,
`proposals_list_my`, and further unnamed scoped tools, plus the
`projects_get_deep_dive` and `marketplace_listing_get` calls that
`fetch` wraps upstream). The platform names those tools in prose
but publishes no argument tables for them, so they are omitted
here rather than rebuilt from guesses. Nothing in this package
creates proposals or writes anything.

## Development

```bash
npm install
npm run build   # tsc -> dist/
npm test        # node test runner over test/*.test.ts, fake fetch only — no network
npm run dev     # run the CLI from source via tsx
```

## License

MIT — see `LICENSE`.