diff --git a/README.md b/README.md index 551a3dd0..6dc781d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,34 @@ -# TakoAPI +
-**One API to access all agents** — an open directory and unified gateway for AI agents (think OpenRouter, but for agents), plus thousands of OpenClaw skills for your coding agent. +# 🐙 TakoAPI + +### One API to access all agents + +An open **directory + unified gateway** for AI agents — think OpenRouter, but for agents — plus thousands of OpenClaw skills for your coding agent. + +[![Live](https://img.shields.io/badge/live-takoapi.com-7c3aed)](https://takoapi.com) +[![GitHub stars](https://img.shields.io/github/stars/oratis/TakoAPI?style=flat&color=7c3aed)](https://github.com/oratis/TakoAPI/stargazers) +[![MCP ready](https://img.shields.io/badge/MCP-ready-7c3aed)](https://takoapi.com/mcp) +[![A2A](https://img.shields.io/badge/protocol-A2A-7c3aed)](https://a2aproject.github.io/A2A/) +[![License: MIT](https://img.shields.io/badge/license-MIT-7c3aed)](LICENSE) +[![Last commit](https://img.shields.io/github/last-commit/oratis/TakoAPI?color=7c3aed)](https://github.com/oratis/TakoAPI/commits) + +**[Live site](https://takoapi.com)** · **[Install](https://takoapi.com/install)** · **[Browse agents](https://takoapi.com/agents)** · **[Skills](https://takoapi.com/skills)** · **[Blog](https://takoapi.com/blog)** + +[![TakoAPI — One API to access all agents](https://takoapi.com/opengraph-image)](https://takoapi.com) + +
+ +> **30 seconds to your first agent call:** install into your coding agent with one command, grab an API key from [the dashboard](https://takoapi.com/dashboard), and invoke any hosted agent through a single endpoint. +> +> ```bash +> curl -fsSL https://takoapi.com/install.sh | sh # 1. teach your agent to use TakoAPI +> curl -H "Authorization: Bearer $TAKO_KEY" \ +> https://takoapi.com/api/registry # 2. discover agents (Markdown for LLMs) +> ``` + + Live at [takoapi.com](https://takoapi.com) @@ -117,6 +145,7 @@ Open [http://localhost:3000](http://localhost:3000). The dev server uses SWC and | `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` | Google OAuth (optional) | | `APPLE_CLIENT_ID` / `APPLE_CLIENT_SECRET` | Apple OAuth (optional) | | `GITHUB_TOKEN` | Raises the GitHub API rate limit for the scraper scripts (optional) | +| `GOOGLE_SITE_VERIFICATION` | Google Search Console verification token(s) for the `google-site-verification` meta tag; comma-separated for multiple (optional) | ## API Reference diff --git a/docs/awesome-a2a-agents-README.md b/docs/awesome-a2a-agents-README.md new file mode 100644 index 00000000..d1451e6d --- /dev/null +++ b/docs/awesome-a2a-agents-README.md @@ -0,0 +1,130 @@ +# Awesome A2A Agents [![Awesome](https://awesome.re/badge.svg)](https://awesome.re) + +> A curated list of awesome resources for the [Agent2Agent (A2A) Protocol](https://a2a-protocol.org/) — the open standard for communication and interoperability between independent AI agents. + +The Agent2Agent (A2A) Protocol is an open standard, originally contributed by Google and now hosted by the Linux Foundation, that lets AI agents built on different frameworks and by different vendors discover one another, exchange messages, and collaborate as agents (not just as tools). This list collects official specs and SDKs, directories and gateways, framework integrations, tools, sample agents, and learning material for the A2A ecosystem. + +## Contents + +- [Official: Spec & Core](#official-spec--core) +- [Directories & Gateways](#directories--gateways) +- [Frameworks & Libraries with A2A Support](#frameworks--libraries-with-a2a-support) +- [Tools & Utilities](#tools--utilities) +- [Example Agents & Samples](#example-agents--samples) +- [Tutorials & Articles](#tutorials--articles) +- [Related Protocols](#related-protocols) +- [Community](#community) +- [Contributing](#contributing) +- [License](#license) + +## Official: Spec & Core + +The canonical protocol and the official SDKs maintained by the [a2aproject](https://github.com/a2aproject) organization under the Linux Foundation. + +- [A2A Protocol](https://github.com/a2aproject/A2A) - The core Agent2Agent (A2A) open protocol specification. +- [A2A .NET SDK](https://github.com/a2aproject/a2a-dotnet) - Official C#/.NET SDK for the A2A Protocol. +- [A2A Documentation Site](https://a2a-protocol.org/) - Official protocol docs, specification, tutorials, and guides. +- [A2A Go SDK](https://github.com/a2aproject/a2a-go) - Official Go SDK for the A2A Protocol. +- [A2A Java SDK](https://github.com/a2aproject/a2a-java) - Official Java SDK for the A2A Protocol. +- [A2A JavaScript SDK](https://github.com/a2aproject/a2a-js) - Official JavaScript/TypeScript SDK for the A2A Protocol. +- [A2A Python SDK](https://github.com/a2aproject/a2a-python) - Official Python SDK for the A2A Protocol. +- [A2A Rust SDK](https://github.com/a2aproject/a2a-rs) - Rust SDK for the A2A Protocol. +- [A2A Samples](https://github.com/a2aproject/a2a-samples) - Official code samples demonstrating the A2A Protocol across languages and frameworks. +- [A2A TCK](https://github.com/a2aproject/a2a-tck) - Technology Compatibility Kit for testing A2A protocol implementations for conformance. + +## Directories & Gateways + +Registries and gateways that help discover, route to, or aggregate A2A-compatible agents. + +- [A2A Registry](https://github.com/prassanna-ravishankar/a2a-registry) - Community-driven, open-source directory of live, hosted agents implementing the A2A Protocol. +- [ContextForge (MCP Context Forge)](https://github.com/IBM/mcp-context-forge) - IBM's open-source gateway, registry, and proxy that federates MCP, A2A, and REST/gRPC APIs behind a unified endpoint. +- [TakoAPI](https://takoapi.com) - Hosted directory and unified API gateway that lets you discover and invoke many AI agents (including A2A-capable ones) through a single endpoint. + +## Frameworks & Libraries with A2A Support + +Agent frameworks and protocol libraries that can expose agents as A2A servers, consume remote A2A agents, or both. + +- [CrewAI](https://github.com/crewAIInc/crewAI) - Multi-agent framework with A2A delegation support via the `crewai[a2a]` extra, acting as A2A client and server. +- [FastA2A](https://github.com/datalayer/fasta2a) - Framework-agnostic Python implementation of the A2A protocol built on Starlette, usable with any agentic framework (ships a Pydantic AI bridge). +- [Google Agent Development Kit (ADK)](https://github.com/google/adk-python) - Google's open-source agent framework with built-in A2A support, including a `to_a2a()` helper to expose agents as A2A servers. +- [LangGraph](https://github.com/langchain-ai/langgraph) - Stateful multi-agent framework from LangChain with A2A agent-card support for serving agents as A2A-compliant endpoints. +- [Microsoft Agent Framework](https://github.com/microsoft/agent-framework) - Microsoft's Python/.NET framework (successor to Semantic Kernel and AutoGen) with cross-runtime A2A and MCP interoperability. +- [python-a2a](https://github.com/themanojdesai/python-a2a) - Third-party, easy-to-use Python library implementing the A2A protocol with agent discovery and MCP support. +- [Semantic Kernel](https://github.com/microsoft/semantic-kernel) - Microsoft's LLM orchestration SDK that supports invoking remote agents exposed over the A2A protocol. + +## Tools & Utilities + +- [A2A Inspector](https://github.com/a2aproject/a2a-inspector) - Web-based tool to connect to, inspect, debug, and validate A2A protocol servers and their agent cards. + +## Example Agents & Samples + +- [A2A-langgraph (langchain-samples)](https://github.com/langchain-samples/A2A-langgraph) - Demonstrates A2A conversations using LangGraph, with Python and TypeScript implementations. +- [A2AWalkthrough](https://github.com/holtskinner/A2AWalkthrough) - Step-by-step walkthrough of the A2A protocol; the basis for the DeepLearning.AI A2A course. +- [a2a-langgraph-agent](https://github.com/ctvs/a2a-langgraph-agent) - Sample showing how a LangGraph ReAct agent can be wrapped with the A2A protocol. + +## Tutorials & Articles + +- [A2A: The Agent2Agent Protocol (DeepLearning.AI)](https://www.deeplearning.ai/courses/a2a-the-agent2agent-protocol) - Short course built with Google Cloud and IBM Research on building and connecting A2A agents. +- [Agent-to-Agent (A2A) Protocol — CrewAI Docs](https://docs.crewai.com/en/learn/a2a-agent-delegation) - Official guide to A2A delegation and serving A2A agents in CrewAI. +- [ADK with the A2A Protocol](https://google.github.io/adk-docs/a2a/) - Official Google ADK documentation for building multi-agent systems with A2A. +- [Getting Started with A2A: Purchasing Concierge (Google Codelab)](https://codelabs.developers.google.com/intro-a2a-purchasing-concierge) - Hands-on codelab deploying A2A agents on Cloud Run and Agent Engine. +- [Inter-Agent Communication on A2A (AWS Open Source Blog)](https://aws.amazon.com/blogs/opensource/open-protocols-for-agent-interoperability-part-4-inter-agent-communication-on-a2a/) - AWS deep dive on A2A as part of its open agent-interoperability protocol series. + +## Related Protocols + +Complementary open standards in the agent-interoperability space. + +- [Agent Connect Protocol (ACP)](https://github.com/agntcy/acp-spec) - AGNTCY collective's specification defining a standard REST interface to invoke and configure remote agents. +- [AGNTCY](https://github.com/agntcy) - Open collective and repos (incl. the ACP SDK) building an "Internet of Agents" infrastructure stack. +- [Model Context Protocol (MCP)](https://github.com/modelcontextprotocol) - Open standard for connecting AI models and agents to external tools and data; commonly used alongside A2A. + +## Community + +- [A2A Protocol Documentation Site](https://a2a-protocol.org/) - Official home for the spec, SDK references, and guides, maintained by the Linux Foundation TSC. +- [a2aproject on GitHub](https://github.com/a2aproject) - Official GitHub organization where the protocol and SDKs are developed; issues and discussions are open to contributors. +- [`a2a` GitHub topic](https://github.com/topics/a2a) - Browse repositories tagged with the A2A topic on GitHub. + +## Contributing + +Contributions are welcome! Please open a pull request to add a resource. To keep this list useful: + +- Only submit **real, verifiable** A2A-related projects with a working GitHub URL or official site. +- Use the format `- [Name](url) - One-line, neutral description ending with a period.` +- Keep entries **alphabetically ordered** within each section. +- Prefer actively maintained, substantive projects over abandoned or trivial ones. + +See [CONTRIBUTING.md](CONTRIBUTING.md) (if present) for full guidelines. + +## License + +[![CC0](https://licensebuttons.net/p/zero/1.0/88x31.png)](https://creativecommons.org/publicdomain/zero/1.0/) + +To the extent possible under law, the maintainers of this list (curated and maintained by [TakoAPI](https://takoapi.com)) have waived all copyright and related or neighboring rights to this work. This list is released under [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/). + + diff --git a/docs/awesome-list-outreach.md b/docs/awesome-list-outreach.md new file mode 100644 index 00000000..c15701f0 --- /dev/null +++ b/docs/awesome-list-outreach.md @@ -0,0 +1,195 @@ +# TakoAPI — Ready-to-Submit "Awesome List" PR Materials + +**Project:** TakoAPI — "One API to access all agents." An open directory + unified gateway for AI agents (OpenRouter-style, but for agents). Exposes an A2A (Agent-to-Agent) directory, an OpenAI-compatible gateway, SSE streaming, a hosted MCP server, and a marketplace of OpenClaw/coding-agent skills. Metered per API key with PayPal top-ups. +**Site:** https://takoapi.com **Repo:** https://github.com/oratis/TakoAPI + +> Research date: 2026-06-27. Facts below were verified by fetching each repo's README / CONTRIBUTING and the GitHub API. Where something could not be verified, it is called out explicitly. Repo URLs were confirmed to resolve (HTTP 200/redirect). Re-check the exact neighboring entries at submission time, since lists change. + +--- + +## Summary table + +| List | Repo | Maintained? | TakoAPI eligible? | Best section | +|---|---|---|---|---| +| awesome-a2a | `ai-boost/awesome-a2a` | Yes — pushed 2026-06-25, 624★ | **Yes** | Tools & Utilities (A2A directory/gateway) | +| awesome-ai-agents | `e2b-dev/awesome-ai-agents` | **Content stale** — last content push 2025-02-26, 28.5k★ | **No / wrong list** — it's "only for AI assistants and agents," not infra. Redirect to sibling list below | n/a | +| └ (redirect) awesome SDKs for AI agents | `e2b-dev/awesome-ai-sdks` | Yes (active PRs) | **Yes** — gateways/tools fit | Agent infrastructure / tools | +| awesome-llm-agents | `kaushikb11/awesome-llm-agents` | Yes — pushed 2026-06-21, 1.5k★ | **Borderline** — list is for *frameworks*, not hosted gateways. See note | Frameworks (weak fit) | +| awesome-mcp (servers) | `wong2/awesome-mcp-servers` | Yes — pushed 2026-06-13, 4.2k★ | **Yes**, but **no PRs accepted** — submit via website form | Community Servers | + +There are multiple competing "awesome-a2a" and "awesome-ai-agents" forks. The most-starred, actively-maintained canonical one is chosen in each case, with alternates listed. + +--- + +## 1. awesome-a2a — `ai-boost/awesome-a2a` + +- **Repo:** https://github.com/ai-boost/awesome-a2a +- **Maintenance:** Active. GitHub API: `pushed_at` = 2026-06-25, 624 stars, not archived, MIT-licensed. ~195 commits at time of research. +- **Eligibility:** **Eligible.** CONTRIBUTING (`/CONTRIBUTING.md`, verified) states inclusion = anything "directly related to Google's Agent2Agent Protocol": implementations, tools, framework integrations, complementary protocols. It **explicitly excludes "promotional content"** and "general AI resources lacking A2A specificity." → Frame TakoAPI as an *A2A directory/gateway*, with a neutral one-line description, **not** marketing copy. No open-source-only rule. +- **Best section:** **Tools & Utilities** (TakoAPI is an A2A agent directory + gateway, not an SDK/library). Sections present: Official Resources · Specification & Core Concepts · Implementations & Libraries · Tools & Utilities · Tutorials & Articles · Demos & Examples · Related Protocols & Concepts · Community. + +**Entry format (verified from CONTRIBUTING):** +`* [Resource Title](link) - A brief, informative description` +Emoji prefix is a tech/type marker (🌟 official, 🐍 Python, ⚙️ tool, 🔗 link, etc.). Ordering within a section is "alphabetical appreciated but not enforced." + +**Exact entry to add (in "Tools & Utilities"):** +```markdown +* ⚙️ [TakoAPI](https://takoapi.com) - Open directory and unified gateway for A2A agents, with an OpenAI-compatible endpoint, SSE streaming, and a hosted MCP server. +``` + +- **Alphabetical position:** Open the section and place "TakoAPI" in its correct alphabetical slot (sorts under "T"). If the section is not alphabetized, append to the end — both are acceptable per CONTRIBUTING. (Exact current neighbors were not enumerated to avoid guessing — confirm at submission.) + +**PR title (follows their `[Emoji] [Action] [Object]` convention):** +``` +✨ Add TakoAPI (A2A directory & unified gateway) to Tools & Utilities +``` + +**PR body:** +``` +Adds TakoAPI to the Tools & Utilities section. + +TakoAPI is an open directory and unified gateway for A2A agents — it exposes an +A2A agent directory, an OpenAI-compatible gateway, SSE streaming, and a hosted +MCP server. Relevance to this list: it implements/consumes the Agent2Agent +protocol as a discovery + routing layer for A2A agents. + +- Site: https://takoapi.com +- Placed alphabetically under "T" in Tools & Utilities. +- Description kept to one neutral sentence per CONTRIBUTING; no promotional language. +``` + +- **Gotchas:** Keep the description factual (their CONTRIBUTING bans promotional content). Use the `⚙️` (tool) emoji, not `🌟` (reserved for official A2A resources). Match the existing emoji-prefix style exactly. +- **Alternate forks (not recommended as primary):** `pab1it0/awesome-a2a`, `forgewebO1/Awesome-A2A`, `isekos/awesome-a2a-agents`. The `a2aproject/*` org is the protocol itself (spec/SDKs/samples), **not** an awesome-list — don't PR there. + +--- + +## 2. awesome-ai-agents — `e2b-dev/awesome-ai-agents` → redirect to `e2b-dev/awesome-ai-sdks` + +- **Repo:** https://github.com/e2b-dev/awesome-ai-agents (28,492★) +- **Maintenance of the *content*:** **Stale.** GitHub API `pushed_at` = **2025-02-26** (≈16 months before research date). `updated_at` only reflects star/metadata changes, not content commits. There is **no `CONTRIBUTING.md`** (verified 404); contribution instructions live in the README. +- **Eligibility:** **Not a fit for this list.** The README states verbatim: *"For adding AI agents'-related SDKs, frameworks and tools, please visit Awesome SDKs for AI Agents. This list is only for AI assistants and agents."* TakoAPI is infrastructure (a gateway/directory/tool), **not an agent/assistant**, so it does not belong here. **Skip this list** and submit to the sibling instead. + +### Redirect target: `e2b-dev/awesome-ai-sdks` (the "SDKs/tools/gateways" list) + +- **Repo:** https://github.com/e2b-dev/awesome-ai-sdks (the README's link `awesome-sdks-for-ai-agents` 301-redirects here — both URLs work). +- **Scope:** "SDKs, frameworks, libraries, and tools for creating, monitoring, debugging and deploying autonomous AI agents." Includes agent-protocol implementations and runtime/infra (E2B, Fixie, observability platforms). A unified API gateway / agent directory fits as **agent infrastructure tooling**. +- **Maintenance:** Active (open PRs/issues). Contribution process: README says *"You have something to add or improve about our list? Do it via pull request."* +- **Eligibility:** **Eligible.** No open-source-only rule observed (commercial/hosted infra like E2B and observability SaaS are listed). +- **Entry format:** e2b collapsible-`
` style (template below). Open the README before submitting and drop TakoAPI into the closest infrastructure/gateway category, alphabetically. (Exact current category headings / open-vs-closed split were not verified.) + +**e2b entry template (mirrors the agents repo's format):** +```markdown +## [TakoAPI](https://takoapi.com) +One API to access all agents — open directory + unified gateway for AI agents. + +
+ +![Image](https://takoapi.com/opengraph-image) + +### Category +Agent gateway, Agent directory, Infrastructure + +### Description + +- **Unified gateway**: One OpenAI-compatible API endpoint to route to many agents. +- **A2A directory**: Open, browsable directory of Agent-to-Agent (A2A) agents. +- **Hosted MCP server**: Exposes tools to agents over the Model Context Protocol. +- **SSE streaming**: Streamed responses for interactive agent use. +- **Skills marketplace**: Directory of OpenClaw / coding-agent skills. +- **Metered billing**: Per-API-key usage metering with PayPal top-ups. + +### Links +- [Website](https://takoapi.com) +- [GitHub](https://github.com/oratis/TakoAPI) +
+``` +> The `![Image]` uses TakoAPI's live OG image (`https://takoapi.com/opengraph-image`). Confirm it returns 200 before submitting — a broken image will fail review. + +**PR title:** +``` +Add TakoAPI (unified agent gateway + A2A directory) +``` +**PR body:** +``` +Adds TakoAPI to the list. + +TakoAPI is a unified gateway and open directory for AI agents: an +OpenAI-compatible API, an A2A agent directory, SSE streaming, and a hosted MCP +server. Submitted here (the SDKs/tools list) rather than awesome-ai-agents, +since per that list's README it is "only for AI assistants and agents" and +TakoAPI is agent infrastructure. + +- Site: https://takoapi.com +- Placed alphabetically under "T" in the relevant infrastructure/gateway category. +``` + +- **Gotchas:** (1) The agents-list README also offers a Google Form (`forms.gle/UXQFCogLYrPFvfoUA`) as an alternative to PRs and requires **alphabetical order within the correct category**. (2) Confirm the SDK repo's actual category names at submission. (3) Provide a working image URL. + +--- + +## 3. awesome-llm-agents — `kaushikb11/awesome-llm-agents` + +- **Repo:** https://github.com/kaushikb11/awesome-llm-agents +- **Maintenance:** Active. API: `pushed_at` = 2026-06-21, 1,516★, not archived. README header says "Last updated: 2026-06-21." **No LICENSE file** (verified 404) — minor, doesn't affect contributions. +- **Eligibility:** **Borderline / weak fit — recommend caution.** This list is explicitly a catalog of **LLM agent *frameworks*** ("frameworks and agent development tools," emphasizing code-based solutions over hosted services). It leans open-source (entries show stars/forks/license, mostly MIT/Apache, e.g. AutoGPT, CrewAI). TakoAPI is a **hosted gateway/directory**, not a framework you install — so it does **not** cleanly match the inclusion theme. The only section is a flat **Frameworks** list, ordered by popularity (star count), **not alphabetical**. +- **Honest recommendation:** **Skip or low-priority.** If submitting anyway, frame TakoAPI as an "agent gateway / development tool," expect possible rejection on scope grounds, and note that entries carry a metrics block (stars/forks/contributors/issues/language/license). +- **Contribution rules:** README invites "open an issue or pull request." **No formal CONTRIBUTING.md found** — no strict entry template confirmed beyond matching the existing metrics-block format. (Unverified.) + +**If submitting anyway, suggested entry (match existing metrics-block style):** +```markdown +### [TakoAPI](https://github.com/oratis/TakoAPI) +One API to access all agents — a unified gateway and open directory for AI agents, with an OpenAI-compatible endpoint, SSE streaming, and a hosted MCP server. + +- One OpenAI-compatible API to route across many agents +- Open A2A (Agent-to-Agent) directory +- Hosted MCP server + SSE streaming +- Metered per-API-key billing +``` +- **Position:** Sorted by star count, so no alphabetical slot — lands wherever its star count falls. +- **PR title:** `Add TakoAPI (agent gateway) to Frameworks` +- **PR body:** State plainly that TakoAPI is a gateway/dev tool for agents and ask maintainers whether it fits the frameworks scope (pre-empt the scope objection). +- **Gotchas:** Not alphabetical (popularity-ordered); entries expect a live metrics block; scope is framework-centric → real rejection risk. +- **Alternates considered:** `hyp1231/awesome-llm-powered-agent` (papers/research), `junhua/awesome-llm-agents` (reading list), `slavakurilyak/awesome-ai-agents`, `kyrolabs/awesome-agents`. None is a better fit for a hosted gateway than the e2b SDKs list above. + +--- + +## 4. awesome-mcp (servers) — `wong2/awesome-mcp-servers` + +- **Repo:** https://github.com/wong2/awesome-mcp-servers +- **Maintenance:** Active. API: `pushed_at` = 2026-06-13, 4,185★, not archived. ~470 commits. +- **Eligibility under inclusion rules:** **Eligible** — the list accepts **remote/hosted** MCP servers, not just locally-runnable ones (it lists fully-remote servers with hosted `https://…/mcp` URLs). TakoAPI's **hosted MCP server qualifies.** Sections: Reference Servers · Official Servers · **Community Servers** (TakoAPI → Community Servers). Entries are alphabetical within each category. No open-source-only requirement observed. +- **CRITICAL gotcha — NO PULL REQUESTS:** README states verbatim: **"We do not accept PRs. Please submit your MCP on the website: https://mcpservers.org/submit"**. There is **no PR to write** — submit through the web form at **https://mcpservers.org/submit**, which feeds both the website and the GitHub list. + +**Form submission content (fields):** +- **Name:** TakoAPI +- **URL / endpoint:** `https://takoapi.com/mcp` (confirm the exact path before submitting; the convention is a directly-usable remote `…/mcp` URL). +- **Homepage:** https://takoapi.com +- **Category:** Community Servers +- **Description (one line, to match list style):** + > Hosted MCP server for TakoAPI — exposes the unified agent gateway and A2A agent directory as MCP tools, usable remotely with no local install. + +**Resulting list entry would render as (their format):** +```markdown +- [TakoAPI](https://takoapi.com) - Hosted, remote MCP server exposing TakoAPI's unified agent gateway and A2A directory as tools (no local install). +``` +- **Gotchas:** (1) **Do not open a GitHub PR — it will be closed.** Use the website form only. (2) Provide a real, working remote MCP URL; "remote" entries are expected to be usable as-is. (3) Sorts alphabetically under "T" within Community Servers (handled by maintainers from the form). +- **Note on the broader MCP ecosystem:** The official `modelcontextprotocol/servers` repo is a curated *reference/official* server list with a strict CONTRIBUTING + test-coverage process and is **not** an "awesome-list" for third-party hosted services — TakoAPI is better placed in `wong2/awesome-mcp-servers` (and optionally `appcypher/awesome-mcp-servers`, an alternate community list whose rules were not fully verified). + +--- + +## What could NOT be fully verified (be honest in the PRs) + +1. **Exact current neighbors** for alphabetical placement in awesome-a2a (Tools & Utilities) and awesome-ai-sdks — the rendered lists group by type, so confirm the precise A–Z slot at submission time. Neighbor names were deliberately not fabricated. +2. **awesome-ai-sdks exact category headings** and whether it splits open/closed-source — open the README before placing the entry. +3. **awesome-llm-agents formal contribution rules** — no CONTRIBUTING.md found; only the README's "open an issue or PR." Treated as unverified. +4. **TakoAPI's exact hosted MCP endpoint path and a valid logo/OG image URL** — verify `https://takoapi.com/mcp` and `https://takoapi.com/opengraph-image` return 200 before submitting (broken links/images are the most common rejection cause). + +## Recommended priority order +1. **awesome-mcp-servers** (web form — fastest, clearly eligible, no PR friction). +2. **awesome-a2a** (`ai-boost`) — strong, on-theme fit; active maintainer. +3. **awesome-ai-sdks** (e2b sibling) — correct home for a gateway; PR or Google Form. +4. **awesome-llm-agents** — optional/low-priority; scope mismatch, expect possible rejection. + +**Skip:** `e2b-dev/awesome-ai-agents` directly (wrong list + content stale ~16 months). + +Sources: [ai-boost/awesome-a2a](https://github.com/ai-boost/awesome-a2a) · [e2b-dev/awesome-ai-agents](https://github.com/e2b-dev/awesome-ai-agents) · [e2b-dev/awesome-ai-sdks](https://github.com/e2b-dev/awesome-ai-sdks) · [kaushikb11/awesome-llm-agents](https://github.com/kaushikb11/awesome-llm-agents) · [wong2/awesome-mcp-servers](https://github.com/wong2/awesome-mcp-servers) · [mcpservers.org/submit](https://mcpservers.org/submit) diff --git a/messages/ar.json b/messages/ar.json index 4ded80cb..85a33c10 100644 --- a/messages/ar.json +++ b/messages/ar.json @@ -33,7 +33,8 @@ "browseSkills": "تصفّح المهارات", "awesomeList": "قائمة Awesome", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. صُمِّم لمجتمع OpenClaw." + "copyright": "© {year} TakoAPI. صُمِّم لمجتمع OpenClaw.", + "blog": "المدونة" }, "Home": { "heroTitle": "واجهة برمجية واحدة للوصول إلى جميع الوكلاء", @@ -656,5 +657,14 @@ "step3Title": "الصقها في README", "step3": "أضِفها قرب الأعلى — يحصل الزوار ومحركات البحث على رابط لصفحتك على TakoAPI.", "findListing": "اعثر على صفحتك" + }, + "Blog": { + "title": "المدونة", + "subtitle": "أدلة حول A2A وبوابات الوكلاء والبناء باستخدام TakoAPI.", + "readMore": "اقرأ المزيد", + "backToBlog": "← كل المقالات", + "minRead": "قراءة {min} دقائق", + "published": "نُشر", + "faqTitle": "الأسئلة الشائعة" } } diff --git a/messages/de.json b/messages/de.json index 70f71adf..f9fda6cf 100644 --- a/messages/de.json +++ b/messages/de.json @@ -33,7 +33,8 @@ "browseSkills": "Skills durchsuchen", "awesomeList": "Awesome-Liste", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. Entwickelt für die OpenClaw-Community." + "copyright": "© {year} TakoAPI. Entwickelt für die OpenClaw-Community.", + "blog": "Blog" }, "Home": { "heroTitle": "Eine API für den Zugriff auf alle Agenten", @@ -656,5 +657,14 @@ "step3Title": "In dein README einfügen", "step3": "Füge es oben ein – Besucher und Suchmaschinen erhalten einen Link zu deiner TakoAPI-Seite.", "findListing": "Eintrag finden" + }, + "Blog": { + "title": "Blog", + "subtitle": "Leitfäden zu A2A, Agent-Gateways und dem Bauen mit TakoAPI.", + "readMore": "Weiterlesen", + "backToBlog": "← Alle Beiträge", + "minRead": "{min} Min. Lesezeit", + "published": "Veröffentlicht", + "faqTitle": "FAQ" } } diff --git a/messages/en.json b/messages/en.json index d212bf76..3a08af2f 100644 --- a/messages/en.json +++ b/messages/en.json @@ -33,7 +33,8 @@ "browseSkills": "Browse Skills", "awesomeList": "Awesome List", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. Built for the OpenClaw community." + "copyright": "© {year} TakoAPI. Built for the OpenClaw community.", + "blog": "Blog" }, "Home": { "heroTitle": "One API to access all agents", @@ -656,5 +657,14 @@ "step3Title": "Paste into your README", "step3": "Add it near the top — visitors and search engines get a link to your TakoAPI page.", "findListing": "Find your listing" + }, + "Blog": { + "title": "Blog", + "subtitle": "Guides on A2A, agent gateways, and building with TakoAPI.", + "readMore": "Read more", + "backToBlog": "← All posts", + "minRead": "{min} min read", + "published": "Published", + "faqTitle": "FAQ" } } diff --git a/messages/es.json b/messages/es.json index 3925346c..6df79e6f 100644 --- a/messages/es.json +++ b/messages/es.json @@ -33,7 +33,8 @@ "browseSkills": "Explorar skills", "awesomeList": "Lista Awesome", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. Creado para la comunidad de OpenClaw." + "copyright": "© {year} TakoAPI. Creado para la comunidad de OpenClaw.", + "blog": "Blog" }, "Home": { "heroTitle": "Una API para acceder a todos los agentes", @@ -656,5 +657,14 @@ "step3Title": "Pégala en tu README", "step3": "Añádela cerca del inicio: visitantes y buscadores obtienen un enlace a tu página de TakoAPI.", "findListing": "Encuentra tu ficha" + }, + "Blog": { + "title": "Blog", + "subtitle": "Guías sobre A2A, gateways de agentes y cómo construir con TakoAPI.", + "readMore": "Leer más", + "backToBlog": "← Todas las entradas", + "minRead": "{min} min de lectura", + "published": "Publicado", + "faqTitle": "Preguntas frecuentes" } } diff --git a/messages/fr.json b/messages/fr.json index 6fa614a2..a961904d 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -33,7 +33,8 @@ "browseSkills": "Parcourir les skills", "awesomeList": "Awesome List", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. Conçu pour la communauté OpenClaw." + "copyright": "© {year} TakoAPI. Conçu pour la communauté OpenClaw.", + "blog": "Blog" }, "Home": { "heroTitle": "Une seule API pour accéder à tous les agents", @@ -656,5 +657,14 @@ "step3Title": "Collez-le dans votre README", "step3": "Ajoutez-le près du haut — visiteurs et moteurs de recherche obtiennent un lien vers votre page TakoAPI.", "findListing": "Trouver votre fiche" + }, + "Blog": { + "title": "Blog", + "subtitle": "Guides sur A2A, les passerelles d'agents et la création avec TakoAPI.", + "readMore": "Lire la suite", + "backToBlog": "← Tous les articles", + "minRead": "{min} min de lecture", + "published": "Publié", + "faqTitle": "FAQ" } } diff --git a/messages/hi.json b/messages/hi.json index 30cf19ab..1d444198 100644 --- a/messages/hi.json +++ b/messages/hi.json @@ -33,7 +33,8 @@ "browseSkills": "स्किल्स ब्राउज़ करें", "awesomeList": "Awesome सूची", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. OpenClaw समुदाय के लिए बनाया गया।" + "copyright": "© {year} TakoAPI. OpenClaw समुदाय के लिए बनाया गया।", + "blog": "ब्लॉग" }, "Home": { "heroTitle": "सभी एजेंट्स तक पहुँचने के लिए एक API", @@ -656,5 +657,14 @@ "step3Title": "README में पेस्ट करें", "step3": "इसे ऊपर की ओर जोड़ें — विज़िटर और सर्च इंजन को आपके TakoAPI पेज का लिंक मिलता है।", "findListing": "अपनी लिस्टिंग खोजें" + }, + "Blog": { + "title": "ब्लॉग", + "subtitle": "A2A, एजेंट गेटवे और TakoAPI के साथ निर्माण पर गाइड।", + "readMore": "और पढ़ें", + "backToBlog": "← सभी लेख", + "minRead": "{min} मिनट का पठन", + "published": "प्रकाशित", + "faqTitle": "अक्सर पूछे जाने वाले प्रश्न" } } diff --git a/messages/id.json b/messages/id.json index ee5f2006..f42713f9 100644 --- a/messages/id.json +++ b/messages/id.json @@ -33,7 +33,8 @@ "browseSkills": "Jelajahi Skill", "awesomeList": "Awesome List", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. Dibuat untuk komunitas OpenClaw." + "copyright": "© {year} TakoAPI. Dibuat untuk komunitas OpenClaw.", + "blog": "Blog" }, "Home": { "heroTitle": "Satu API untuk mengakses semua agen", @@ -656,5 +657,14 @@ "step3Title": "Tempel ke README", "step3": "Tambahkan di dekat atas — pengunjung dan mesin pencari mendapat tautan ke halaman TakoAPI Anda.", "findListing": "Temukan halaman Anda" + }, + "Blog": { + "title": "Blog", + "subtitle": "Panduan tentang A2A, gateway agen, dan membangun dengan TakoAPI.", + "readMore": "Baca selengkapnya", + "backToBlog": "← Semua artikel", + "minRead": "{min} mnt baca", + "published": "Diterbitkan", + "faqTitle": "FAQ" } } diff --git a/messages/it.json b/messages/it.json index f7944338..f30dc9fc 100644 --- a/messages/it.json +++ b/messages/it.json @@ -33,7 +33,8 @@ "browseSkills": "Esplora le skill", "awesomeList": "Awesome List", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. Realizzato per la community OpenClaw." + "copyright": "© {year} TakoAPI. Realizzato per la community OpenClaw.", + "blog": "Blog" }, "Home": { "heroTitle": "Un'unica API per accedere a tutti gli agenti", @@ -656,5 +657,14 @@ "step3Title": "Incollalo nel tuo README", "step3": "Aggiungilo in alto: visitatori e motori di ricerca ottengono un link alla tua pagina TakoAPI.", "findListing": "Trova la tua scheda" + }, + "Blog": { + "title": "Blog", + "subtitle": "Guide su A2A, gateway per agenti e su come costruire con TakoAPI.", + "readMore": "Leggi di più", + "backToBlog": "← Tutti gli articoli", + "minRead": "{min} min di lettura", + "published": "Pubblicato", + "faqTitle": "Domande frequenti" } } diff --git a/messages/ja.json b/messages/ja.json index 7d5ea11b..7accc47f 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -33,7 +33,8 @@ "browseSkills": "スキルを見る", "awesomeList": "Awesomeリスト", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. OpenClawコミュニティのために構築。" + "copyright": "© {year} TakoAPI. OpenClawコミュニティのために構築。", + "blog": "ブログ" }, "Home": { "heroTitle": "ひとつのAPIで、すべてのエージェントに", @@ -656,5 +657,14 @@ "step3Title": "README に貼り付け", "step3": "上部付近に追加すると、訪問者や検索エンジンが TakoAPI ページへのリンクを得られます。", "findListing": "掲載ページを探す" + }, + "Blog": { + "title": "ブログ", + "subtitle": "A2A、エージェントゲートウェイ、TakoAPI での構築に関するガイド。", + "readMore": "続きを読む", + "backToBlog": "← 記事一覧", + "minRead": "約 {min} 分で読めます", + "published": "公開日", + "faqTitle": "よくある質問" } } diff --git a/messages/ko.json b/messages/ko.json index 2e01ef9b..a9f71723 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -33,7 +33,8 @@ "browseSkills": "스킬 둘러보기", "awesomeList": "Awesome 목록", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. OpenClaw 커뮤니티를 위해 만들었습니다." + "copyright": "© {year} TakoAPI. OpenClaw 커뮤니티를 위해 만들었습니다.", + "blog": "블로그" }, "Home": { "heroTitle": "모든 에이전트에 접근하는 단 하나의 API", @@ -656,5 +657,14 @@ "step3Title": "README에 붙여넣기", "step3": "상단 근처에 추가하면 방문자와 검색엔진이 TakoAPI 페이지로 연결됩니다.", "findListing": "등록 페이지 찾기" + }, + "Blog": { + "title": "블로그", + "subtitle": "A2A, 에이전트 게이트웨이, TakoAPI로 빌드하는 방법에 대한 가이드.", + "readMore": "더 읽기", + "backToBlog": "← 전체 글", + "minRead": "{min}분 분량", + "published": "게시일", + "faqTitle": "자주 묻는 질문" } } diff --git a/messages/pt.json b/messages/pt.json index a9b900ac..49d35fb9 100644 --- a/messages/pt.json +++ b/messages/pt.json @@ -33,7 +33,8 @@ "browseSkills": "Navegar pelas skills", "awesomeList": "Awesome List", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. Feito para a comunidade OpenClaw." + "copyright": "© {year} TakoAPI. Feito para a comunidade OpenClaw.", + "blog": "Blog" }, "Home": { "heroTitle": "Uma API para acessar todos os agentes", @@ -656,5 +657,14 @@ "step3Title": "Cole no seu README", "step3": "Adicione perto do topo — visitantes e buscadores recebem um link para sua página no TakoAPI.", "findListing": "Encontre sua página" + }, + "Blog": { + "title": "Blog", + "subtitle": "Guias sobre A2A, gateways de agentes e como construir com a TakoAPI.", + "readMore": "Ler mais", + "backToBlog": "← Todos os artigos", + "minRead": "{min} min de leitura", + "published": "Publicado", + "faqTitle": "Perguntas frequentes" } } diff --git a/messages/ru.json b/messages/ru.json index dac6c9d8..1be4c155 100644 --- a/messages/ru.json +++ b/messages/ru.json @@ -33,7 +33,8 @@ "browseSkills": "Просмотр навыков", "awesomeList": "Awesome-список", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. Создано для сообщества OpenClaw." + "copyright": "© {year} TakoAPI. Создано для сообщества OpenClaw.", + "blog": "Блог" }, "Home": { "heroTitle": "Один API для доступа ко всем агентам", @@ -656,5 +657,14 @@ "step3Title": "Вставьте в README", "step3": "Добавьте ближе к началу — посетители и поисковики получат ссылку на вашу страницу TakoAPI.", "findListing": "Найти свою страницу" + }, + "Blog": { + "title": "Блог", + "subtitle": "Руководства по A2A, шлюзам агентов и разработке с TakoAPI.", + "readMore": "Читать далее", + "backToBlog": "← Все статьи", + "minRead": "{min} мин чтения", + "published": "Опубликовано", + "faqTitle": "Частые вопросы" } } diff --git a/messages/tr.json b/messages/tr.json index abf7a8a3..c643a24c 100644 --- a/messages/tr.json +++ b/messages/tr.json @@ -33,7 +33,8 @@ "browseSkills": "Becerilere Gözat", "awesomeList": "Awesome Listesi", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. OpenClaw topluluğu için geliştirildi." + "copyright": "© {year} TakoAPI. OpenClaw topluluğu için geliştirildi.", + "blog": "Blog" }, "Home": { "heroTitle": "Tüm ajanlara erişmek için tek API", @@ -656,5 +657,14 @@ "step3Title": "README'nize yapıştırın", "step3": "Üst kısma ekleyin — ziyaretçiler ve arama motorları TakoAPI sayfanıza bağlantı alır.", "findListing": "Sayfanızı bulun" + }, + "Blog": { + "title": "Blog", + "subtitle": "A2A, agent ağ geçitleri ve TakoAPI ile geliştirme üzerine rehberler.", + "readMore": "Devamını oku", + "backToBlog": "← Tüm yazılar", + "minRead": "{min} dk okuma", + "published": "Yayınlandı", + "faqTitle": "SSS" } } diff --git a/messages/vi.json b/messages/vi.json index 57f7f437..af18fcd0 100644 --- a/messages/vi.json +++ b/messages/vi.json @@ -33,7 +33,8 @@ "browseSkills": "Duyệt kỹ năng", "awesomeList": "Awesome List", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI. Xây dựng cho cộng đồng OpenClaw." + "copyright": "© {year} TakoAPI. Xây dựng cho cộng đồng OpenClaw.", + "blog": "Blog" }, "Home": { "heroTitle": "Một API để truy cập mọi agent", @@ -656,5 +657,14 @@ "step3Title": "Dán vào README", "step3": "Thêm gần đầu trang — khách truy cập và công cụ tìm kiếm có liên kết đến trang TakoAPI của bạn.", "findListing": "Tìm trang của bạn" + }, + "Blog": { + "title": "Blog", + "subtitle": "Hướng dẫn về A2A, cổng agent và xây dựng với TakoAPI.", + "readMore": "Đọc thêm", + "backToBlog": "← Tất cả bài viết", + "minRead": "Đọc {min} phút", + "published": "Đã đăng", + "faqTitle": "Câu hỏi thường gặp" } } diff --git a/messages/zh.json b/messages/zh.json index 20498976..1823ab07 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -33,7 +33,8 @@ "browseSkills": "浏览技能", "awesomeList": "精选清单", "clawHub": "ClawHub", - "copyright": "© {year} TakoAPI。为 OpenClaw 社区打造。" + "copyright": "© {year} TakoAPI。为 OpenClaw 社区打造。", + "blog": "博客" }, "Home": { "heroTitle": "一个 API,访问所有智能体", @@ -656,5 +657,14 @@ "step3Title": "粘贴到 README", "step3": "放在顶部附近——访客和搜索引擎都能链接到你的 TakoAPI 页面。", "findListing": "找到你的收录页" + }, + "Blog": { + "title": "博客", + "subtitle": "关于 A2A、Agent 网关,以及如何用 TakoAPI 构建的指南。", + "readMore": "阅读全文", + "backToBlog": "← 所有文章", + "minRead": "约 {min} 分钟阅读", + "published": "发布于", + "faqTitle": "常见问题" } } diff --git a/src/app/[locale]/blog/[slug]/page.tsx b/src/app/[locale]/blog/[slug]/page.tsx new file mode 100644 index 00000000..929cffe8 --- /dev/null +++ b/src/app/[locale]/blog/[slug]/page.tsx @@ -0,0 +1,136 @@ +import { getTranslations, setRequestLocale } from "next-intl/server"; +import { notFound } from "next/navigation"; +import { Link } from "@/i18n/navigation"; +import { JsonLd } from "@/components/JsonLd"; +import { getPost } from "@/lib/blog"; +import { absoluteUrl, SITE_NAME, SITE_URL, localizedAlternates } from "@/lib/seo"; +import { localeOg } from "@/lib/locales"; +import { routing } from "@/i18n/routing"; + +export async function generateMetadata({ params }: { params: Promise<{ locale: string; slug: string }> }) { + const { locale, slug } = await params; + const post = getPost(slug); + if (!post) return {}; + const isDefault = locale === routing.defaultLocale; + return { + metadataBase: new URL(absoluteUrl("")), + title: post.title, + description: post.description, + keywords: post.tags, + alternates: localizedAlternates(locale, `/blog/${slug}`), + // English is the canonical, indexable version; other locales render the same + // English body and are noindexed to avoid near-duplicate penalties. + ...(isDefault ? {} : { robots: { index: false, follow: true } }), + openGraph: { + title: `${post.title} — ${SITE_NAME}`, + description: post.description, + url: absoluteUrl(`/blog/${slug}`), + type: "article", + publishedTime: post.datePublished, + modifiedTime: post.dateModified, + locale: localeOg(locale), + images: [absoluteUrl("/opengraph-image")], + }, + twitter: { card: "summary_large_image", title: `${post.title} — ${SITE_NAME}`, description: post.description }, + }; +} + +export default async function BlogPostPage({ params }: { params: Promise<{ locale: string; slug: string }> }) { + const { locale, slug } = await params; + setRequestLocale(locale); + const post = getPost(slug); + if (!post) notFound(); + + const t = await getTranslations("Blog"); + const canonical = absoluteUrl(`/blog/${slug}`); + + const articleLd = { + "@context": "https://schema.org", + "@type": "BlogPosting", + headline: post.title, + description: post.description, + datePublished: post.datePublished, + dateModified: post.dateModified, + url: canonical, + mainEntityOfPage: canonical, + image: absoluteUrl("/opengraph-image"), + keywords: post.tags.join(", "), + author: { "@type": "Organization", name: SITE_NAME, url: SITE_URL }, + publisher: { + "@type": "Organization", + name: SITE_NAME, + url: SITE_URL, + logo: { "@type": "ImageObject", url: absoluteUrl("/icon.svg") }, + }, + }; + const breadcrumbLd = { + "@context": "https://schema.org", + "@type": "BreadcrumbList", + itemListElement: [ + { "@type": "ListItem", position: 1, name: SITE_NAME, item: absoluteUrl("/") }, + { "@type": "ListItem", position: 2, name: t("title"), item: absoluteUrl("/blog") }, + { "@type": "ListItem", position: 3, name: post.title, item: canonical }, + ], + }; + const faqLd = post.faq?.length + ? { + "@context": "https://schema.org", + "@type": "FAQPage", + mainEntity: post.faq.map((f) => ({ + "@type": "Question", + name: f.q, + acceptedAnswer: { "@type": "Answer", text: f.a }, + })), + } + : null; + + return ( +
+ + + {faqLd && } + + + {t("backToBlog")} + + +
+
+ {post.tags.map((tag) => ( + + {tag} + + ))} + · {t("minRead", { min: post.readingMinutes })} +
+

{post.title}

+

{post.description}

+

+ {t("published")} +

+
+ +
+ + {post.faq?.length ? ( +
+

{t("faqTitle")}

+
+ {post.faq.map((f) => ( +
+
{f.q}
+
{f.a}
+
+ ))} +
+
+ ) : null} + +
+ + {t("backToBlog")} + +
+
+ ); +} diff --git a/src/app/[locale]/blog/page.tsx b/src/app/[locale]/blog/page.tsx new file mode 100644 index 00000000..e56c962d --- /dev/null +++ b/src/app/[locale]/blog/page.tsx @@ -0,0 +1,95 @@ +import { getTranslations, setRequestLocale } from "next-intl/server"; +import { Link } from "@/i18n/navigation"; +import { JsonLd } from "@/components/JsonLd"; +import { getAllPosts } from "@/lib/blog"; +import { absoluteUrl, SITE_NAME, localizedAlternates } from "@/lib/seo"; +import { localeOg } from "@/lib/locales"; +import { routing } from "@/i18n/routing"; + +export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) { + const { locale } = await params; + const t = await getTranslations({ locale, namespace: "Blog" }); + const title = t("title"); + const description = t("subtitle"); + // English is the canonical, indexable content; non-English locales render the + // same English body and are marked noindex to avoid near-duplicate penalties + // (same defense the entity pages use). + const isDefault = locale === routing.defaultLocale; + return { + metadataBase: new URL(absoluteUrl("")), + title, + description, + alternates: localizedAlternates(locale, "/blog"), + ...(isDefault ? {} : { robots: { index: false, follow: true } }), + openGraph: { + title: `${title} — ${SITE_NAME}`, + description, + url: absoluteUrl("/blog"), + type: "website", + locale: localeOg(locale), + images: [absoluteUrl("/opengraph-image")], + }, + twitter: { card: "summary_large_image", title: `${title} — ${SITE_NAME}`, description }, + }; +} + +export default async function BlogIndexPage({ params }: { params: Promise<{ locale: string }> }) { + const { locale } = await params; + setRequestLocale(locale); + const t = await getTranslations("Blog"); + const posts = getAllPosts(); + + const listLd = { + "@context": "https://schema.org", + "@type": "Blog", + name: `${SITE_NAME} — ${t("title")}`, + description: t("subtitle"), + url: absoluteUrl("/blog"), + blogPost: posts.map((p) => ({ + "@type": "BlogPosting", + headline: p.title, + description: p.description, + datePublished: p.datePublished, + dateModified: p.dateModified, + url: absoluteUrl(`/blog/${p.slug}`), + })), + }; + + return ( +
+ +
+

{t("title")}

+

{t("subtitle")}

+
+ +
+ {posts.map((p) => ( +
+
+ {p.tags.map((tag) => ( + + {tag} + + ))} + · {t("minRead", { min: p.readingMinutes })} +
+

+ {p.title} +

+

{p.description}

+ + {t("readMore")} → + +
+ ))} +
+
+ ); +} diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index 93a11c5e..7a5a6f17 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -67,6 +67,18 @@ export async function generateMetadata({ "max-video-preview": -1, }, }, + // Search Console domain verification (GTM §0). Set GOOGLE_SITE_VERIFICATION + // to the token from the GSC "HTML tag" method and redeploy — Next renders + // . Omitted entirely when unset, and + // only meaningful on the canonical English pages (others are noindexed), + // but harmless to emit everywhere. Supports a comma-separated list. + ...(process.env.GOOGLE_SITE_VERIFICATION + ? { + verification: { + google: process.env.GOOGLE_SITE_VERIFICATION.split(",").map((s) => s.trim()), + }, + } + : {}), category: "technology", }; } diff --git a/src/app/api/badge/[slug]/route.ts b/src/app/api/badge/[slug]/route.ts index 1907512c..8bdc72cf 100644 --- a/src/app/api/badge/[slug]/route.ts +++ b/src/app/api/badge/[slug]/route.ts @@ -1,5 +1,6 @@ import { NextRequest, NextResponse } from "next/server"; import { prisma } from "@/lib/prisma"; +import { logRequest } from "@/lib/requestLog"; export const dynamic = "force-dynamic"; @@ -58,16 +59,29 @@ function svgResponse(svg: string, status: number, maxAge: number): NextResponse }); } -export async function GET(_req: NextRequest, { params }: { params: Promise<{ slug: string }> }) { +export async function GET(req: NextRequest, { params }: { params: Promise<{ slug: string }> }) { + const start = Date.now(); const { slug } = await params; + + // Log every render so badge adoption is quantifiable: path is per-slug + // (`/api/badge/`, covered by RequestLog's [path, createdAt] index), so + // counting rows per path = renders per repo. Note: when the badge is embedded + // in a GitHub README, GitHub's camo proxy fetches it and strips Referer, so + // attribution is by slug + volume, not by referring page. Fire-and-forget; + // never blocks or fails the SVG response. + const log = (status: number) => + logRequest({ req, path: `/api/badge/${slug}`, status, durationMs: Date.now() - start }); + const agent = await prisma.agent.findFirst({ where: { OR: [{ slug }, { id: slug }], status: "APPROVED" }, select: { kind: true, stars: true }, }); if (!agent) { + log(404); return svgResponse(badgeSvg("TakoAPI", "not listed"), 404, 300); } const value = agent.kind === "PROJECT" && typeof agent.stars === "number" ? `★ ${fmtStars(agent.stars)}` : "listed"; + log(200); return svgResponse(badgeSvg("TakoAPI", value), 200, 600); } diff --git a/src/app/globals.css b/src/app/globals.css index cbf0d2ec..154b0075 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -19,3 +19,86 @@ body { -webkit-box-orient: vertical; overflow: hidden; } + +/* Article typography for blog posts (trusted HTML from src/lib/blog.ts). + Scoped to .blog-prose so it never leaks into the rest of the app — we don't + pull in @tailwindcss/typography for a handful of marketing pages. */ +.blog-prose { + color: #374151; + line-height: 1.75; +} +.blog-prose > * + * { + margin-top: 1.1rem; +} +.blog-prose h2 { + font-size: 1.5rem; + font-weight: 700; + color: #111827; + margin-top: 2.25rem; + margin-bottom: 0.5rem; +} +.blog-prose h3 { + font-size: 1.2rem; + font-weight: 600; + color: #111827; + margin-top: 1.5rem; + margin-bottom: 0.25rem; +} +.blog-prose a { + color: #7c3aed; + text-decoration: underline; + text-underline-offset: 2px; +} +.blog-prose a:hover { + color: #6d28d9; +} +.blog-prose ul, +.blog-prose ol { + padding-left: 1.5rem; +} +.blog-prose ul { + list-style: disc; +} +.blog-prose ol { + list-style: decimal; +} +.blog-prose li + li { + margin-top: 0.35rem; +} +.blog-prose pre { + background: #0f172a; + color: #e2e8f0; + padding: 1rem; + border-radius: 0.5rem; + overflow-x: auto; + font-size: 0.875rem; +} +.blog-prose :not(pre) > code { + background: #f3f4f6; + padding: 0.1rem 0.35rem; + border-radius: 0.25rem; + font-size: 0.875em; +} +.blog-prose table { + width: 100%; + border-collapse: collapse; + font-size: 0.9rem; + display: block; + overflow-x: auto; +} +.blog-prose th, +.blog-prose td { + border: 1px solid #e5e7eb; + padding: 0.5rem 0.75rem; + text-align: left; + vertical-align: top; +} +.blog-prose th { + background: #f9fafb; + font-weight: 600; + color: #111827; +} +.blog-prose strong { + color: #111827; + font-weight: 600; +} diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts index da82f756..6d7f10d8 100644 --- a/src/app/sitemap.ts +++ b/src/app/sitemap.ts @@ -3,6 +3,7 @@ import { prisma } from "@/lib/prisma"; import { localizedUrl } from "@/lib/seo"; import { routing } from "@/i18n/routing"; import { SCENARIOS } from "@/lib/scenarios"; +import { getAllPosts } from "@/lib/blog"; // Generated at request time against the live catalog (the app renders DB pages // dynamically and the Docker build has no DB), so the sitemap stays fresh as @@ -55,8 +56,17 @@ export default async function sitemap(): Promise { entry("/install", { lastModified: now, changeFrequency: "monthly", priority: 0.6 }), entry("/badge", { lastModified: now, changeFrequency: "monthly", priority: 0.5 }), entry("/trending", { lastModified: now, changeFrequency: "weekly", priority: 0.6 }), + entry("/blog", { lastModified: now, changeFrequency: "weekly", priority: 0.7 }), ]; + const blogRoutes: MetadataRoute.Sitemap = getAllPosts().map((p) => + entry(`/blog/${p.slug}`, { + lastModified: new Date(p.dateModified), + changeFrequency: "monthly", + priority: 0.6, + }), + ); + const agentRoutes: MetadataRoute.Sitemap = agents.map((a) => entry(`/agents/${a.slug}`, { lastModified: a.updatedAt, changeFrequency: "weekly", priority: 0.7 }), ); @@ -69,5 +79,5 @@ export default async function sitemap(): Promise { entry(`/scenarios/${s.slug}`, { lastModified: now, changeFrequency: "weekly", priority: 0.6 }), ); - return [...staticRoutes, ...scenarioRoutes, ...agentRoutes, ...skillRoutes]; + return [...staticRoutes, ...blogRoutes, ...scenarioRoutes, ...agentRoutes, ...skillRoutes]; } diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx index ac9df394..d0fc43d5 100644 --- a/src/components/layout/Footer.tsx +++ b/src/components/layout/Footer.tsx @@ -34,6 +34,7 @@ export default async function Footer() {
  • {t("publishAnAgent")}
  • {t("developerDashboard")}
  • {t("browseSkills")}
  • +
  • {t("blog")}
  • diff --git a/src/lib/blog.ts b/src/lib/blog.ts new file mode 100644 index 00000000..ca232d78 --- /dev/null +++ b/src/lib/blog.ts @@ -0,0 +1,295 @@ +// ───────────────────────────────────────────────────────────── +// Blog / content registry — depth content for SEO weight (GTM §5). +// +// Defined in code (not the unused `BlogPost` DB model) so posts are +// reviewable, version-controlled, and ship with the build — no migration, +// no seeding, no DB round-trip on render. Each post's `body` is trusted +// HTML authored here (NOT user input), rendered with dangerouslySetInnerHTML +// on the article page. +// +// Strategy note: these are English-first marketing/explainer pages. The +// English URLs are the canonical, indexable ones; non-English locales render +// the same English body but are emitted `noindex` (matching the near-duplicate +// defense the rest of the app already uses) so we never risk machine-translated +// thin-content penalties. To add a post: append to POSTS, keep dates ISO, and +// cross-link other posts/scenarios with absolute in-app paths. +// ───────────────────────────────────────────────────────────── + +export interface BlogPost { + /** stable slug used in the URL: /blog/ */ + slug: string; + /** + H1 */ + title: string; + /** meta description + list blurb (~150–160 chars) */ + description: string; + /** ISO date (YYYY-MM-DD) */ + datePublished: string; + /** ISO date (YYYY-MM-DD) */ + dateModified: string; + /** short topic tags shown as chips */ + tags: string[]; + /** rough reading time in minutes, shown in the list/header */ + readingMinutes: number; + /** trusted HTML body (authored here, never user input) */ + body: string; + /** optional Q&A → FAQPage structured data + on-page FAQ */ + faq?: { q: string; a: string }[]; +} + +// Shared CTA appended to every article body. +const CTA = ` +<aside class="not-prose my-8 rounded-xl border border-purple-200 bg-purple-50 p-5"> + <p class="font-semibold text-gray-900">Try it in 30 seconds</p> + <p class="mt-1 text-sm text-gray-600">Discover and invoke any hosted agent through one API. Browse the open <a href="/agents">agent directory</a>, or install TakoAPI into your coding agent:</p> + <pre class="mt-3 overflow-x-auto rounded-lg bg-gray-900 p-3 text-sm text-gray-100"><code>curl -fsSL https://takoapi.com/install.sh | sh</code></pre> +</aside>`; + +export const POSTS: BlogPost[] = [ + { + slug: "what-is-a2a", + title: "What is A2A (Agent2Agent)? The agent interoperability protocol, explained", + description: + "A2A is an open protocol that lets independent AI agents discover and talk to each other across vendors. Here's how AgentCards, tasks, and messages work — with examples.", + datePublished: "2026-06-27", + dateModified: "2026-06-27", + tags: ["A2A", "protocols", "interoperability"], + readingMinutes: 7, + body: ` +<p><strong>A2A (Agent2Agent)</strong> is an open protocol for letting independent AI agents discover one another and collaborate — even when they were built by different teams, on different frameworks, behind different clouds. Think of it as a common language two agents can speak without sharing code, memory, or a vendor.</p> + +<p>It was introduced by Google in 2025 and is now stewarded as an open project. The goal is narrow and useful: give an agent a standard way to <em>find</em> another agent, <em>describe</em> what it can do, and <em>delegate</em> a unit of work to it.</p> + +<h2>The problem A2A solves</h2> +<p>Most agents today are islands. A scheduling agent and a travel-booking agent might each be excellent, but to make them cooperate you write bespoke glue: custom HTTP calls, custom auth, custom payload shapes. Multiply that by every pair of agents and integration cost explodes. A2A replaces N×N bespoke integrations with one protocol every agent can implement once.</p> + +<h2>The three core concepts</h2> +<h3>1. The AgentCard</h3> +<p>Every A2A agent publishes an <strong>AgentCard</strong> — a small JSON document (conventionally at <code>/.well-known/agent.json</code>) that advertises its identity, endpoint URL, supported skills, input/output modes, and authentication requirements. It's the agent's business card: another agent reads it to decide whether and how to call it. This is what makes agents <em>discoverable</em> rather than hard-coded.</p> + +<h3>2. Tasks</h3> +<p>Work in A2A is modeled as a <strong>task</strong> with a lifecycle: <code>submitted → working → input-required → completed</code> (or <code>failed</code>/<code>canceled</code>). Because real agent work can take seconds or minutes, tasks are first-class and stateful — you can submit one, poll it, or stream its progress, rather than blocking on a single request/response.</p> + +<h3>3. Messages and artifacts</h3> +<p>Within a task, the calling agent and the remote agent exchange <strong>messages</strong> (turns of a conversation) made of <em>parts</em> — text, files, or structured data. The remote agent's deliverables come back as <strong>artifacts</strong>. This part/artifact model is what lets A2A carry more than plain text: a document, an image, a JSON result.</p> + +<h2>What a call looks like</h2> +<p>At the wire level A2A is JSON-RPC over HTTP, with Server-Sent Events for streaming. Conceptually:</p> +<ol> + <li>Fetch the remote agent's <strong>AgentCard</strong> to learn its URL and auth.</li> + <li>Send a <code>message/send</code> (or <code>message/stream</code>) request that opens a <strong>task</strong>.</li> + <li>Receive streamed updates as the task moves through its states, then collect the final <strong>artifacts</strong>.</li> +</ol> + +<h2>Where TakoAPI fits</h2> +<p>A2A standardizes the <em>conversation</em> between two agents, but you still have to find agents, manage an API key per agent, and handle each one's billing and uptime. <a href="/agents">TakoAPI</a> is a directory and gateway on top of A2A: every listed agent is described by its AgentCard, and you invoke any of them through one endpoint and one key — A2A passthrough, SSE streaming, or an OpenAI-compatible shim. It's the "OpenRouter for agents" layer that A2A makes possible.</p> +${CTA} +<p class="text-sm text-gray-500">Related: <a href="/blog/a2a-vs-mcp">A2A vs MCP</a> · <a href="/blog/one-api-for-all-agents">How to call multiple agents through one API</a></p> +`, + faq: [ + { + q: "Is A2A the same as MCP?", + a: "No. MCP (Model Context Protocol) connects a single model to tools and data sources. A2A connects independent agents to each other. They're complementary — an agent can use MCP for its tools and A2A to delegate to other agents.", + }, + { + q: "Who created A2A?", + a: "A2A (Agent2Agent) was introduced by Google in 2025 and is developed as an open protocol so any vendor or framework can implement it.", + }, + { + q: "What is an AgentCard?", + a: "An AgentCard is a small JSON document an A2A agent publishes to advertise its endpoint, skills, input/output modes, and auth — the metadata other agents read to discover and call it.", + }, + ], + }, + { + slug: "a2a-vs-mcp", + title: "A2A vs MCP: how Agent2Agent and Model Context Protocol differ (and work together)", + description: + "A2A connects agents to other agents; MCP connects a model to tools and data. Here's a side-by-side comparison of the two protocols and when to use each.", + datePublished: "2026-06-27", + dateModified: "2026-06-27", + tags: ["A2A", "MCP", "protocols"], + readingMinutes: 6, + body: ` +<p>A2A and MCP are the two protocols you'll hear about most when building with agents, and they're constantly confused. The short version: <strong>MCP connects a model to its tools; A2A connects an agent to other agents.</strong> They operate at different layers and are designed to be used together, not chosen between.</p> + +<h2>Side by side</h2> +<table> + <thead> + <tr><th> </th><th>MCP (Model Context Protocol)</th><th>A2A (Agent2Agent)</th></tr> + </thead> + <tbody> + <tr><td><strong>Connects</strong></td><td>One model/agent → tools, files, data sources</td><td>One agent → other independent agents</td></tr> + <tr><td><strong>Question it answers</strong></td><td>"What can this agent <em>do</em> / reach?"</td><td>"Who else can I <em>delegate</em> this to?"</td></tr> + <tr><td><strong>Unit of work</strong></td><td>Tool call (function with arguments)</td><td>Task (stateful, long-running, streamable)</td></tr> + <tr><td><strong>Discovery</strong></td><td>Server lists its tools</td><td>Agent publishes an AgentCard</td></tr> + <tr><td><strong>Typical caller</strong></td><td>The LLM inside one agent</td><td>An agent acting as a client of another agent</td></tr> + <tr><td><strong>Introduced by</strong></td><td>Anthropic (2024)</td><td>Google (2025)</td></tr> + </tbody> +</table> + +<h2>An analogy</h2> +<p>If an agent were a worker: <strong>MCP is the worker's toolbox</strong> — the drills, the database access, the file cabinet they reach for. <strong>A2A is the worker calling a colleague</strong> in another department to hand off a job they can't do themselves. You want both. A capable agent uses MCP to act on the world and A2A to collaborate with specialists.</p> + +<h2>A concrete flow</h2> +<p>Say you ask a "trip planner" agent to book a vacation:</p> +<ol> + <li>The planner uses <strong>MCP</strong> to call a calendar tool and a weather API (its own tools).</li> + <li>It then uses <strong>A2A</strong> to delegate "book this flight" to a dedicated flight-booking agent and "reserve this hotel" to a hotel agent — independent agents it discovered, not tools it owns.</li> + <li>Each delegated <strong>task</strong> streams progress back; the planner assembles the results.</li> +</ol> + +<h2>When to reach for which</h2> +<ul> + <li><strong>Use MCP</strong> when you're giving <em>one</em> agent access to tools, APIs, files, or databases.</li> + <li><strong>Use A2A</strong> when you want <em>separate</em> agents — possibly from different vendors — to cooperate on a job.</li> +</ul> + +<h2>How TakoAPI uses both</h2> +<p>TakoAPI is an A2A directory and gateway: agents are described by AgentCards and invoked over A2A through one key. It's <em>also</em> exposed as a hosted <strong>MCP server</strong>, so a coding agent can register TakoAPI once and get <code>search_agents</code>, <code>get_agent</code>, and <code>invoke_agent</code> as native tools — using MCP to reach into an A2A directory. That's the two protocols composing exactly as intended.</p> +${CTA} +<p class="text-sm text-gray-500">Related: <a href="/blog/what-is-a2a">What is A2A?</a> · <a href="/blog/takoapi-vs-openrouter">TakoAPI vs OpenRouter</a></p> +`, + faq: [ + { + q: "Should I use A2A or MCP?", + a: "Usually both. Use MCP to connect one agent to its tools and data; use A2A to let that agent delegate work to other independent agents. They sit at different layers and compose.", + }, + { + q: "Does A2A replace MCP?", + a: "No. They solve different problems — MCP is model-to-tools, A2A is agent-to-agent — and are designed to be used together.", + }, + ], + }, + { + slug: "one-api-for-all-agents", + title: "How to call multiple AI agents through one API", + description: + "Stop managing a separate SDK, key, and billing setup per agent. Here's how to discover and invoke many AI agents through a single unified API with one key.", + datePublished: "2026-06-27", + dateModified: "2026-06-27", + tags: ["gateway", "API", "how-to"], + readingMinutes: 5, + body: ` +<p>The moment you use more than one hosted agent, integration tax kicks in: a different base URL, a different auth scheme, a different request shape, and a separate invoice for each. A unified <strong>agent gateway</strong> collapses all of that into one endpoint, one key, and one bill — the same move OpenRouter made for language models, applied to agents.</p> + +<h2>The pattern</h2> +<p>A gateway sits in front of many agents and gives you three things:</p> +<ul> + <li><strong>One directory</strong> to discover agents (by capability, scenario, or popularity).</li> + <li><strong>One credential</strong> — a single API key that works across every agent.</li> + <li><strong>One protocol surface</strong> — call any agent the same way, with metering and billing handled centrally.</li> +</ul> + +<h2>Step 1 — discover agents</h2> +<p>Ask the registry for the catalog. It returns Markdown by default (ideal to drop straight into an LLM's context) or JSON:</p> +<pre><code>curl "https://takoapi.com/api/registry?format=json&q=research"</code></pre> + +<h2>Step 2 — get a key</h2> +<p>Create an API key in the <a href="/dashboard">dashboard</a>. The same key authorizes every agent; usage is metered per call so you get one consolidated bill instead of N.</p> + +<h2>Step 3 — invoke any agent</h2> +<p>Call a hosted agent through the gateway. Three surfaces are available depending on your client:</p> +<pre><code># A2A passthrough +curl -X POST https://takoapi.com/v1/agents/<slug>/message \\ + -H "Authorization: Bearer $TAKO_KEY" \\ + -H "Content-Type: application/json" \\ + -d '{"message":{"role":"user","parts":[{"text":"Summarize this URL ..."}]}}' + +# Streaming (Server-Sent Events) +curl https://takoapi.com/v1/agents/<slug>/stream -H "Authorization: Bearer $TAKO_KEY" ... + +# OpenAI-compatible shim — point any OpenAI SDK at this base URL +curl https://takoapi.com/v1/chat/completions -H "Authorization: Bearer $TAKO_KEY" ...</code></pre> + +<p>The OpenAI-compatible surface is the fastest path if you already have code using an OpenAI SDK: change the base URL and key, and you're calling agents instead of raw models — no new SDK to learn.</p> + +<h2>Step 4 (optional) — let your coding agent do it</h2> +<p>If you live in Claude Code, Codex, or OpenCode, install TakoAPI as a skill or MCP server and your agent gains <code>search_agents</code> / <code>invoke_agent</code> natively:</p> +<pre><code>curl -fsSL https://takoapi.com/install.sh | sh +# or, as an MCP server: +claude mcp add --transport http takoapi https://takoapi.com/mcp</code></pre> + +<h2>Why route through a gateway at all</h2> +<ul> + <li><strong>Less code</strong> — one integration instead of one per agent.</li> + <li><strong>One bill</strong> — metered centrally; top up once.</li> + <li><strong>Swap freely</strong> — try a different agent for the same job by changing a slug, not rewriting an integration.</li> +</ul> +${CTA} +<p class="text-sm text-gray-500">Related: <a href="/blog/what-is-a2a">What is A2A?</a> · <a href="/blog/takoapi-vs-openrouter">TakoAPI vs OpenRouter</a></p> +`, + }, + { + slug: "takoapi-vs-openrouter", + title: "TakoAPI vs OpenRouter: a gateway for agents vs a gateway for models", + description: + "OpenRouter gives you one API for many LLMs. TakoAPI gives you one API for many agents. Here's how the two differ and when each is the right tool.", + datePublished: "2026-06-27", + dateModified: "2026-06-27", + tags: ["comparison", "gateway", "OpenRouter"], + readingMinutes: 5, + body: ` +<p>People often describe TakoAPI as "OpenRouter for agents," which is the right instinct — both are unified gateways with one key and one bill. The difference is the <em>unit</em> they route to. <strong>OpenRouter routes to models; TakoAPI routes to agents.</strong> That distinction changes what you send, what you get back, and what the gateway does for you.</p> + +<h2>Side by side</h2> +<table> + <thead> + <tr><th> </th><th>OpenRouter</th><th>TakoAPI</th></tr> + </thead> + <tbody> + <tr><td><strong>Routes to</strong></td><td>Language models (GPT, Claude, Llama …)</td><td>AI agents (hosted, task-completing)</td></tr> + <tr><td><strong>Unit of work</strong></td><td>A completion / chat turn</td><td>A task — possibly multi-step, tool-using, long-running</td></tr> + <tr><td><strong>Native protocol</strong></td><td>OpenAI chat-completions</td><td>A2A (+ OpenAI-compatible shim + SSE)</td></tr> + <tr><td><strong>Discovery</strong></td><td>Model list</td><td>Agent directory + open-source project directory + scenarios</td></tr> + <tr><td><strong>Describes capability via</strong></td><td>Model name + context window</td><td>AgentCard (skills, I/O modes, auth)</td></tr> + <tr><td><strong>Also a coding-agent tool?</strong></td><td>—</td><td>Yes — installs as a skill / MCP server</td></tr> + </tbody> +</table> + +<h2>The real distinction: model vs agent</h2> +<p>A <strong>model</strong> takes a prompt and returns text. An <strong>agent</strong> takes a goal and does work toward it — calling tools, taking multiple steps, sometimes delegating to other agents — then returns a result. OpenRouter is the right abstraction when you want to pick the best <em>model</em> for a prompt. TakoAPI is the right abstraction when you want to hand off a <em>job</em> to something that completes it.</p> + +<h2>They're not mutually exclusive</h2> +<p>Many agents are built <em>on</em> models — and some of those models may be served through OpenRouter. You can use OpenRouter at the model layer inside your own agent and use TakoAPI at the agent layer to discover and invoke other agents. They sit at different altitudes of the same stack.</p> + +<h2>When to choose TakoAPI</h2> +<ul> + <li>You want to <strong>discover and call task-completing agents</strong>, not just raw models.</li> + <li>You need <strong>A2A</strong> (AgentCards, stateful tasks, streaming) — with an OpenAI-compatible shim for drop-in use.</li> + <li>You want your <strong>coding agent</strong> (Claude Code, Codex, OpenCode) to discover and invoke agents as a native skill or MCP tool.</li> + <li>You want <strong>one key and one bill</strong> across many agents, metered per call.</li> +</ul> + +<h2>When to choose OpenRouter</h2> +<ul> + <li>You're routing among <strong>language models</strong> and want price/availability fallback across providers.</li> +</ul> + +<p>Different layer, different job. If your question is "which model answers this prompt best," reach for a model gateway. If it's "which agent gets this task done," that's what <a href="/agents">TakoAPI</a> is for.</p> +${CTA} +<p class="text-sm text-gray-500">Related: <a href="/blog/one-api-for-all-agents">Call multiple agents through one API</a> · <a href="/blog/a2a-vs-mcp">A2A vs MCP</a></p> +`, + faq: [ + { + q: "Is TakoAPI just OpenRouter for agents?", + a: "That's a good shorthand. Both are unified gateways with one key and one bill, but OpenRouter routes to language models and TakoAPI routes to task-completing agents over A2A (with an OpenAI-compatible shim).", + }, + { + q: "Can I use TakoAPI and OpenRouter together?", + a: "Yes. They sit at different layers — you can use OpenRouter for model routing inside your own agent and TakoAPI to discover and invoke other agents.", + }, + ], + }, +]; + +const BY_SLUG = new Map(POSTS.map((p) => [p.slug, p])); + +/** All posts, newest first. */ +export function getAllPosts(): BlogPost[] { + return [...POSTS].sort((a, b) => (a.datePublished < b.datePublished ? 1 : -1)); +} + +/** Look up a single post by slug (undefined if not found). */ +export function getPost(slug: string): BlogPost | undefined { + return BY_SLUG.get(slug); +}