# Faro > Faro is an AI agent marketplace. One account gives an agent access to every tool from every publisher — authenticate with a single Bearer token and invoke through a unified gateway. Faro handles billing (prepaid credits) and upstream provider auth (publisher API keys are stored as Faro connections and forwarded as headers), so agents never sign up, pay, or manage credentials per publisher. One account, one token, every tool. Browse the marketplace at https://askfaro.com/search. ## Start here - [Quickstart](https://askfaro.com/llms/quickstart.md): minimal 3-step path from token → invocation. - [Buyer skill (agent recipe)](https://askfaro.com/llms/skill.md): the search → describe → invoke loop, with budget guardrails. ## Discovery - [Tool search](https://askfaro.com/llms/search.md): how to find the right tool with semantic search. - Live search endpoint: https://api.askfaro.com/tools/search?q={query} - Browse namespaces: https://api.askfaro.com/namespaces/public - Sitemap (all public listings): https://askfaro.com/sitemap.xml - Markdown mirrors for each listing live under https://askfaro.com/llms/namespaces/{namespace}.md and https://askfaro.com/llms/namespaces/{namespace}/{tool}.md ## Invocation - [HTTP invocation](https://askfaro.com/llms/invoke.md): auth, request shape, errors, idempotency. - [CLI invocation](https://askfaro.com/llms/cli.md): `askfaro-cli` — search/describe/invoke from a shell. - OpenAPI spec: https://api.askfaro.com/openapi.json - Structured API guide (JSON): https://api.askfaro.com/docs/ ## Publishing - [Publisher guide](https://askfaro.com/llms/publish.md): list your MCP server on Faro. ## Full inlined version - [llms-full.txt](https://askfaro.com/llms-full.txt) — everything above, inlined for one-shot ingestion. ## Pricing 1,000 credits = $1.00 USD (1 credit = $0.001). Buyers prepay credits; publishers set per-tool pricing. Faro's margin is bundled into displayed prices. --- # Faro quickstart One Faro account gives your agent access to every tool in the marketplace — no per-publisher signups, payments, or API keys. One Bearer token, three steps: ## 1. Get an API key Sign up at https://askfaro.com/register (free credits on signup), then create a key: ``` POST https://api.askfaro.com/tokens/ Authorization: Bearer Content-Type: application/json {"name": "my-agent"} ``` Or, if you can run a shell: ``` pip install askfaro-cli faro auth login # paste the faro_ key ``` ## 2. Find a tool Semantic search across all active namespaces: ``` GET https://api.askfaro.com/tools/search?q=find+the+ceo+of+a+company ``` Each hit includes `namespace`, `name`, `input_schema`, and `pricing`. No second lookup needed. CLI equivalent: ``` faro search "find the ceo of a company" ``` ## 3. Invoke it ``` POST https://api.askfaro.com/invoke/{namespace}/{tool_name} Authorization: Bearer faro_ Content-Type: application/json {"arguments": { ... }} ``` CLI: ``` faro invoke {namespace}/{tool_name} --params '{"...": "..."}' ``` The response includes the tool result, credits charged, and your remaining balance. ## What's next - [Skill recipe](https://askfaro.com/llms/skill.md) — the loop an agent should follow. - [Invoke reference](https://askfaro.com/llms/invoke.md) — errors, idempotency, partner tokens. - [CLI reference](https://askfaro.com/llms/cli.md) — every command. --- # Buyer agent skill (search → describe → invoke) This is the recipe an autonomous agent should follow when given a task that might require a marketplace tool. One Faro account covers every publisher in the marketplace, so the agent never has to detour to sign up, pay, or fetch credentials for a new provider mid-task — and never needs a human in the loop after token issuance. ## Loop 1. **Decide if you need a tool.** If the task is purely reasoning, don't shop. If it needs external action (fetch, scrape, generate, send), continue. 2. **Search.** Call `GET https://api.askfaro.com/tools/search?q={natural-language-query}` or `faro search ""`. Use the user's intent verbatim; the index is semantic. 3. **Rank candidates.** Each result has `namespace/name`, `short_description`, `pricing`, and `input_schema`. Prefer (a) lowest credit cost that meets the requirement, (b) tools whose schema matches the data you have, (c) tools with `charge_on: success` over `attempt`. 4. **Describe (optional).** If the search result didn't include enough context, fetch https://api.askfaro.com/docs/namespaces/{slug}/{tool_name} for the full input_schema, long_description, and curl example. CLI: `faro describe {namespace}/{tool_name}`. 5. **Check budget.** `GET https://api.askfaro.com/credits/balance` returns your remaining credits. If a tool's `fixed_credit_cost` exceeds your remaining budget, stop and surface the gap to your user. 6. **Invoke.** `POST https://api.askfaro.com/invoke/{namespace}/{tool_name}` with `{"arguments": {...}}`. Pass an `idempotency_key` if the operation must not double-charge on retry. 7. **Handle the response.** On 200, the body contains the tool output plus billing metadata. On 402, you ran out of credits — surface to your user. On 502, the upstream tool failed — Faro auto-refunds when `charge_on: success`. ## Guardrails - **Pass-through pricing.** What you see is what you pay; Faro's margin is already bundled into the displayed price. - **One token, many tools.** Don't fetch per-publisher credentials — Faro forwards them server-side. - **Stable error codes.** 401 unauthorized, 402 insufficient credits, 404 not found, 409 idempotency conflict, 502 upstream failure. - **Partner integrations.** If you're a partner platform invoking on behalf of an end user, use a `faro_partner_` token with the `X-Faro-User` header — usage is attributed to that user's balance. ## Minimal pseudocode ``` hits = GET /tools/search?q= best = pick(hits, by=cost_then_match) balance = GET /credits/balance if best.pricing.fixed_credit_cost > balance: stop result = POST /invoke/{best.namespace}/{best.name} with arguments ``` --- # Tool search Faro's search is semantic over every public tool in every active namespace. Agents should pass natural-language queries verbatim from their user's intent. ## HTTP ``` GET https://api.askfaro.com/tools/search?q={query}&limit={n} ``` - `q` — natural-language query, e.g. `find+the+CEO+of+a+company` - `limit` — default 10, max 50 - No auth required for search. Each result: ```json { "namespace": "...", "name": "...", "short_description": "...", "input_schema": { ... }, "pricing": { "pricing_mode": "fixed_per_request", "fixed_credit_cost": 50, "charge_on": "success" } } ``` The `input_schema` is included in search results so you can invoke without a second round-trip. ## CLI ``` faro search "find the CEO of a company" ``` Outputs the same JSON when stdout is piped. ## Browse - All active namespaces: https://api.askfaro.com/namespaces/public - Single namespace: https://api.askfaro.com/namespaces/public/{slug} - Single tool: https://api.askfaro.com/tools/{namespace}/{tool_name} - Markdown listing mirror: https://askfaro.com/llms/namespaces/{namespace}.md - Markdown tool mirror: https://askfaro.com/llms/namespaces/{namespace}/{tool_name}.md - Public sitemap: https://askfaro.com/sitemap.xml --- # Tool invocation The unified gateway. One account, one token, one endpoint — every tool from every publisher. ## Endpoint ``` POST https://api.askfaro.com/invoke/{namespace}/{tool_name} Authorization: Bearer faro_ Content-Type: application/json { "arguments": { ... }, // matches the tool's input_schema "idempotency_key": "..." // optional; prevents duplicate charges on retry } ``` ## Auth Three token types accepted on `/invoke`: | Prefix | Use case | Extra headers | |---|---|---| | `faro_` | Personal / agent API key | — | | `` | Logged-in session | — | | `faro_partner_` | Partner platform invoking for an end user | `X-Faro-User: ` | Create a personal key: `POST https://api.askfaro.com/tokens/` (requires JWT from `POST https://api.askfaro.com/auth/login`). ## Response ```json { "result": { ... }, // upstream tool output, as-is "credits_charged": 50, "credits_remaining": 9950, "invocation_id": "inv_..." } ``` ## Errors | Code | Meaning | |---|---| | 401 | Missing or invalid token | | 402 | Insufficient credits — call `POST /credits/purchase` | | 404 | Namespace or tool not found | | 409 | Duplicate `idempotency_key` | | 502 | Upstream tool failed — auto-refunded when pricing is `charge_on: success` | ## Idempotency Pass `idempotency_key` for any operation that has external side-effects (sending emails, posting messages, charging cards). Faro stores the first response keyed on that string for 24 hours and replays it on retries. ## Pricing modes - `fixed_per_request` — Tool charges `fixed_credit_cost` per call. - `tool_returned` — Tool returns its cost in the response (e.g. token-based pricing for LLM tools). 1,000 credits = $1.00 USD. The price shown on a listing is what you pay end-to-end; Faro's margin is bundled in. ## See also - [CLI invocation](https://askfaro.com/llms/cli.md) - OpenAPI spec: https://api.askfaro.com/openapi.json - Structured guide (JSON): https://api.askfaro.com/docs/ --- # askfaro-cli `askfaro-cli` is the official command-line client. It wraps every API endpoint, outputs JSON when stdout is piped (agent-friendly), and uses stable exit codes for errors. ## Install ``` pip install askfaro-cli ``` Or bootstrap with no install: ``` npx askfaro ``` ## Authenticate ``` faro auth login --email you@example.com # password prompt → mints + saves an API key faro auth login # paste an existing key ``` Credentials live at `~/.config/faro/credentials`. You can also set `FARO_API_KEY` in your environment, or pass `--api-key` per-call. API keys cannot mint other API keys; all key creation goes through the email+password flow. Use `faro tokens list` / `faro tokens revoke ` to manage existing keys. ## Buyer commands ``` faro search "" # semantic search; returns JSON faro describe / # full input_schema + pricing + curl faro invoke / --params '' # invoke with inline JSON faro invoke / --params-file args.json echo '{"to":"a@b.com"}' | faro invoke / faro invoke / --params '{...}' --dry-run # validate against schema ``` Examples: ``` faro search "send an email" faro describe acme/send-email faro invoke acme/send-email --params '{"to":"user@example.com","subject":"Hi"}' ``` ## Account commands ``` faro doctor # check auth + publisher status + namespace health ``` ## Publisher commands ``` faro publisher register --display-name 'Acme' faro ns quick-setup --namespace acme --mcp-url https://mcp.acme.dev faro init acme # writes faro.yaml + README.md faro push --publish # save manifest + submit for review faro ns check acme # local validation faro pull acme # pull latest server state into faro.yaml faro diff # show local vs server diff ``` ## Output - TTY: pretty-printed. - Piped or `--json`: machine-readable JSON on stdout. - Errors: JSON envelope on stderr, stable exit codes (`EXIT_AUTH`, `EXIT_VALIDATION`, `EXIT_NOT_FOUND`, `EXIT_API`, `EXIT_NETWORK`). ## Why CLI for agents `faro search` returns each result with its `input_schema` already attached, so an agent can search → invoke in two shell calls. No second describe round-trip required unless you need long_description or examples. ## Source - npm bootstrap: https://askfaro.com/cli (npx askfaro) - PyPI: `askfaro-cli` --- # Publishing on Faro Faro fronts your existing MCP server with auth, billing, and discovery. You bring the server; Faro brings the buyers. ## What you ship - An MCP-compatible HTTP endpoint (`https://mcp.yourdomain.com`) implementing the tools you want to monetize. - A `faro.yaml` manifest declaring the namespace, listing copy, tools, and pricing. ## Path ``` pip install askfaro-cli faro auth login faro publisher register --display-name 'Acme' faro ns quick-setup --namespace acme --mcp-url https://mcp.acme.dev faro init acme # generates faro.yaml + README.md $EDITOR faro.yaml # description, tags, example_prompts, pricing faro ns check acme # local validation faro push --publish # save + submit for review ``` ## Pricing Set `pricing_mode: fixed_per_request` with a credit cost per tool group, or `tool_returned` to let your tool report its own cost (token-priced tools, etc.). 1,000 credits = $1.00 USD. Faro's margin is bundled into the price the buyer sees — don't reference your gross or our cut in user-facing copy. ## Upstream auth Buyer-side, every request to Faro carries a single `faro_` Bearer. Faro forwards your upstream credentials (stored once as a Faro `connection`) as headers when proxying to your MCP server. Buyers never see them. ## Reviews Every listing goes through a human review before going public. Use `faro ns check` first — it flags missing copy, broken schemas, and obvious smoke-test failures. ## Reference - Full publisher API docs: https://api.askfaro.com/docs/ - CLI reference: https://askfaro.com/llms/cli.md - Marketplace: https://askfaro.com/search