From 648e81416be9cc8482bf3f4b75a55174c405cddd Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Sat, 8 Aug 2026 21:07:54 -0300 Subject: [PATCH] docs(radar): document guided combos and MCP --- AGENTS.md | 28 +++++++++++------------ README.md | 8 +++---- docs/architecture/QUALITY_GATES.md | 8 +++---- docs/frameworks/MCP-SERVER.md | 25 ++++++++++---------- docs/frameworks/RADAR.md | 26 ++++++++++++++++++--- open-sse/mcp-server/README.md | 27 +++++++++++++--------- scripts/check/check-docs-counts-sync.mjs | 5 ++-- tests/unit/check-docs-counts-sync.test.ts | 10 ++++---- 8 files changed, 81 insertions(+), 56 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index f88c9056a5..feda2fb478 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -48,20 +48,20 @@ Repository map and Reference Documentation sections below. **OmniRoute** — unified AI proxy/router. One endpoint, 291 LLM providers, auto-fallback. -| Layer | Location | Purpose | -| ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| API Routes | `src/app/api/v1/` | Next.js App Router — entry points | -| Handlers | `open-sse/handlers/` | Request processing (chat, embeddings, etc) | -| Executors | `open-sse/executors/` | Provider-specific HTTP dispatch | -| Translators | `open-sse/translator/` | Format conversion (OpenAI↔Claude↔Gemini) | -| Transformer | `open-sse/transformer/` | Responses API ↔ Chat Completions | -| Services | `open-sse/services/` | Combo routing, rate limits, caching, etc | -| Database | `src/lib/db/` | SQLite domain modules (130 migrations) | -| Domain/Policy | `src/domain/` | Policy engine, cost rules, fallback logic | -| MCP Server | `open-sse/mcp-server/` | 105 tools (42 base + memory/skill/agentSkill/pool/notion/obsidian/gamification/plugin modules), 3 transports (stdio / SSE / Streamable HTTP), 31 scopes | -| A2A Server | `src/lib/a2a/` | JSON-RPC 2.0 agent protocol | -| Skills | `src/lib/skills/` | Extensible skill framework | -| Memory | `src/lib/memory/` | Persistent conversational memory | +| Layer | Location | Purpose | +| ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| API Routes | `src/app/api/v1/` | Next.js App Router — entry points | +| Handlers | `open-sse/handlers/` | Request processing (chat, embeddings, etc) | +| Executors | `open-sse/executors/` | Provider-specific HTTP dispatch | +| Translators | `open-sse/translator/` | Format conversion (OpenAI↔Claude↔Gemini) | +| Transformer | `open-sse/transformer/` | Responses API ↔ Chat Completions | +| Services | `open-sse/services/` | Combo routing, rate limits, caching, etc | +| Database | `src/lib/db/` | SQLite domain modules (130 migrations) | +| Domain/Policy | `src/domain/` | Policy engine, cost rules, fallback logic | +| MCP Server | `open-sse/mcp-server/` | 109 tools (44 canonical + memory/skill/GitHub/pool/gamification/plugin/Notion/Obsidian/local-corpus/RTK modules), 3 transports (stdio / SSE / Streamable HTTP), 33 scopes | +| A2A Server | `src/lib/a2a/` | JSON-RPC 2.0 agent protocol | +| Skills | `src/lib/skills/` | Extensible skill framework | +| Memory | `src/lib/memory/` | Persistent conversational memory | Monorepo: `src/` (Next.js 16 app), `open-sse/` (streaming engine workspace), `electron/` (desktop app), `tests/`, `bin/` (CLI entry point). diff --git a/README.md b/README.md index 352619a7f0..5edc2d69c7 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,7 @@ curl http://localhost:20128/v1/chat/completions \ -The Promise — One endpoint. 291 providers. Never stop building — OmniRoute picks the cheapest one that works. Six pillars: Never hit limits (auto-fallback across 291 providers in milliseconds, zero downtime) · Save up to 95% tokens (RTK + Caveman stacked compression cuts 15–95%, ~89% avg on tool-heavy sessions) · $0 to start (90+ free tiers, 40+ free forever — no card needed) · Every tool works (33 coding agents through one config) · One endpoint (OpenAI ↔ Claude ↔ Gemini ↔ Responses API at /v1) · Production-grade (circuit breakers, TLS stealth, MCP 105 tools, A2A, memory, guardrails, evals — 25,000+ tests). +The Promise — One endpoint. 291 providers. Never stop building — OmniRoute picks the cheapest one that works. Six pillars: Never hit limits (auto-fallback across 291 providers in milliseconds, zero downtime) · Save up to 95% tokens (RTK + Caveman stacked compression cuts 15–95%, ~89% avg on tool-heavy sessions) · $0 to start (90+ free tiers, 40+ free forever — no card needed) · Every tool works (33 coding agents through one config) · One endpoint (OpenAI ↔ Claude ↔ Gemini ↔ Responses API at /v1) · Production-grade (circuit breakers, TLS stealth, MCP 109 tools, A2A, memory, guardrails, evals — 25,000+ tests).

@@ -439,7 +439,7 @@ All **19** strategies — mix & match per combo step: -What sets OmniRoute apart — comparison table vs 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute: 291 providers, 90+ free providers built-in, 19 routing strategies, 12-engine token compression, built-in MCP server with 105 tools, A2A agent protocol, persistent memory, guardrails, cloud agents, TLS fingerprint stealth, Desktop/Termux/PWA, 43 i18n UI locales, 100% MIT self-hosted. OmniRoute is the only one with the full set; competitors show a mix of checks, partials and crosses. Verified from each project's docs. +What sets OmniRoute apart — comparison table vs 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute: 291 providers, 90+ free providers built-in, 19 routing strategies, 12-engine token compression, built-in MCP server with 109 tools, A2A agent protocol, persistent memory, guardrails, cloud agents, TLS fingerprint stealth, Desktop/Termux/PWA, 43 i18n UI locales, 100% MIT self-hosted. OmniRoute is the only one with the full set; competitors show a mix of checks, partials and crosses. Verified from each project's docs. 📊 Full methodology & per-feature detail vs 9router, OpenRouter, CLIProxyAPI & LiteLLM → [`docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md`](docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md) @@ -723,7 +723,7 @@ Expose OmniRoute over **MCP**, **A2A**, a **REST API**, **webhooks** or a **remo - + @@ -1110,7 +1110,7 @@ same process on one port, so there is no separate CLI-only package today. - + diff --git a/docs/architecture/QUALITY_GATES.md b/docs/architecture/QUALITY_GATES.md index 06c55e99cf..b7e279525f 100644 --- a/docs/architecture/QUALITY_GATES.md +++ b/docs/architecture/QUALITY_GATES.md @@ -186,10 +186,10 @@ Runs on pull requests only. Runs after `build`. Blocks merge on failure. -| Suite | Validates | Blocking | -| ---------------- | ------------------------------------------------------- | -------------------------------------------------------------------------- | -| `test:vitest` | MCP server (94 tools), autoCombo, cache — vitest runner | Yes | -| `test:vitest:ui` | UI component tests — vitest runner | **Advisory** (`continue-on-error: true`) — failing until Fase 6A UI triage | +| Suite | Validates | Blocking | +| ---------------- | -------------------------------------------------------- | -------------------------------------------------------------------------- | +| `test:vitest` | MCP server (109 tools), autoCombo, cache — vitest runner | Yes | +| `test:vitest:ui` | UI component tests — vitest runner | **Advisory** (`continue-on-error: true`) — failing until Fase 6A UI triage | ### Nightly workflows (scheduled, advisory) diff --git a/docs/frameworks/MCP-SERVER.md b/docs/frameworks/MCP-SERVER.md index 710315cf49..7a8e40db39 100644 --- a/docs/frameworks/MCP-SERVER.md +++ b/docs/frameworks/MCP-SERVER.md @@ -1,14 +1,14 @@ --- title: "OmniRoute MCP Server Documentation" -version: 3.8.40 -lastUpdated: 2026-06-28 +version: 3.8.50 +lastUpdated: 2026-08-08 --- # OmniRoute MCP Server Documentation -> Model Context Protocol server with 105 tools across routing, cache, compression, memory, skills, proxy, pool, and context source operations. +> Model Context Protocol server with 109 tools across routing, cache, compression, memory, skills, proxy, pool, Radar, and context source operations. > -> Source of truth: `open-sse/mcp-server/server.ts` computes **104 unique tools** with `countUniqueMcpTools()`: 42 canonical definitions (including the six CCR lifecycle tools and the agent-skills trio), plus memory (3), skills (4), GitHub skills (3), pool (6), gamification (8), plugins (8), Notion (6), Obsidian (22), and two RTK-only compression tools. +> Source of truth: `open-sse/mcp-server/server.ts` computes **109 unique tools** with `countUniqueMcpTools()`: 44 canonical definitions (including the six CCR lifecycle tools, the agent-skills trio, and `omniroute_radar_catalog`), plus memory (3), skills (4), GitHub skills (3), pool (6), gamification (8), plugins (8), Notion (6), Obsidian (22), local corpus (3), and two RTK-only compression tools. ## Installation @@ -64,7 +64,7 @@ Cursor, Cline, and compatible MCP client setup. --- -## Essential Tools (8) — Phase 1 +## Essential Tools (13) — Phase 1 | Tool | Scopes | Description | | :------------------------------ | :-------------------- | :------------------------------------------------------------ | @@ -72,16 +72,15 @@ Cursor, Cline, and compatible MCP client setup. | `omniroute_list_combos` | `read:combos` | All configured combos with strategies (optional metrics) | | `omniroute_get_combo_metrics` | `read:combos` | Performance metrics for a specific combo | | `omniroute_switch_combo` | `write:combos` | Activate or deactivate a combo | +| `omniroute_create_combo` | `write:combos` | Create a validated combo through the existing combo API | | `omniroute_check_quota` | `read:quota` | Quota used/total, percent remaining, reset time, token health | | `omniroute_route_request` | `execute:completions` | Send a chat completion through OmniRoute routing | | `omniroute_cost_report` | `read:usage` | Cost report by period (session/day/week/month) | | `omniroute_list_models_catalog` | `read:models` | Full model catalog with capabilities, status, pricing | - -## Phase 1 — Search - -| Tool | Scopes | Description | -| :--------------------- | :--------------- | :--------------------------------------------------------------------------------------------------------------------------------- | -| `omniroute_web_search` | `execute:search` | Web search through OmniRoute search gateway (Serper/Brave/Perplexity/Exa/Tavily/Google PSE/Linkup/SearchAPI/SearXNG) with failover | +| `omniroute_radar_catalog` | `read:radar` | Local signed Radar catalog; optional provider/family filters | +| `omniroute_tool_search` | `read:tools` | Discover tools from the registered MCP catalog | +| `omniroute_web_search` | `execute:search` | Web search through the configured search providers | +| `omniroute_web_fetch` | `execute:search` | Fetch web content through the configured fetch providers | ## Advanced Tools (11) — Phase 2 @@ -227,7 +226,7 @@ See [AGENT-SKILLS.md](./AGENT-SKILLS.md) for the full catalog and how external a ## Related Frameworks (v3.8.0) -The MCP tool inventory above (104 unique tools, computed by `countUniqueMcpTools()`) is intentionally +The MCP tool inventory above (109 unique tools, computed by `countUniqueMcpTools()`) is intentionally scoped to runtime routing/cache/compression/memory/skills/proxy/context-source operations. Two adjacent frameworks ship alongside the MCP server in v3.8.0 and are documented separately: @@ -369,7 +368,7 @@ MCP tool, prompt, and resource registries can compress descriptions at registrat Description compression shrinks each tool's metadata; **tool-cardinality reduction** goes one step further by reducing _how many_ tools are announced at all. Advertising fewer tools in the `tools/list` manifest cuts the per-request token cost the client's model pays for the tool catalog ("layer 5" compression). The implementation is a pure, stateless filter in `open-sse/mcp-server/toolCardinality.ts` (`reduceToolManifest`), wired into the registration loop in `createMcpServer()` (`open-sse/mcp-server/server.ts`). -**Opt-in, off by default.** The filter only runs when at least one of two environment variables is set; with neither set, all 105 tools are announced unchanged. +**Opt-in, off by default.** The filter only runs when at least one of two environment variables is set; with neither set, all 109 tools are announced unchanged. | Variable | Mode | | :--------------- | :-------------------------------------------------------------------------------------- | diff --git a/docs/frameworks/RADAR.md b/docs/frameworks/RADAR.md index 1d1d1015d7..1e36a4e228 100644 --- a/docs/frameworks/RADAR.md +++ b/docs/frameworks/RADAR.md @@ -290,6 +290,26 @@ The dashboard exposes four local actions: A feed `enabled: false` remains the safety exception: it wins over a stale local `enabled: true`, keeps the merged entry disabled, and records `disabledBy: "radar"`. +### Guided combos and MCP access + +Confirmed `familyId` values survive the read-time overlay and drive the pure +`buildRadarComboSuggestions()` module (`src/lib/radar/comboSuggestions.ts`). A family is suggested +only when at least two distinct providers have active connections and expose the exact curated model +ID. Disabled models, inactive providers, missing model IDs, singleton families, and ambiguous +alias/prefix matches fail closed. Suggestions use the existing `priority` strategy, ordering the +largest recurring monthly budget first; the UI creates them only through `POST /api/combos`. + +The guided UI lives at `/dashboard/radar/combos`. It reads only the local +`GET /api/radar/catalog` and `GET /api/combos/builder/options` endpoints. It never triggers Radar sync, +reads provider credentials, or writes directly to the combo database. + +MCP clients can read the same local projection with `omniroute_radar_catalog` (`read:radar`). The +optional `provider`, `familyId`, and `enabledOnly` filters are evaluated after one local +`GET /api/radar/catalog` read. Its closed output includes catalog metadata plus provider/model, +display name, `familyId`, quota, capabilities, enabled state, origin, and `disabledBy`; setup URLs, +steps, connections, e-mail addresses, keys, and referral data are never returned. This tool is +read-only and never invokes `/api/radar/sync`. + ### Provenance markers Every merged entry carries an `origin` field the UI renders as a badge: @@ -303,7 +323,7 @@ Every merged entry carries an `origin` field the UI renders as a badge: ## Local surfaces — never a feed proxy -Six local endpoints back the UI, all under `src/app/api/radar/`: +The local Radar route families below back the UI under `src/app/api/radar/`: | Route | Method | Purpose | | ------------------------------ | ------ | --------------------------------------------------------------------------------------------------------------------- | @@ -323,14 +343,14 @@ to the local OmniRoute server. The two modules that touch the Radar service are always run server-side, never client-side. This keeps the feed URL and any supporter key out of client-facing network traffic entirely. -All six endpoints return `404` when `RADAR_ENABLED` is off (see +All Radar endpoints return `404` when `RADAR_ENABLED` is off (see [Flag](#flag-radar_enabled-default-off) above), and route error responses through `buildErrorBody()`/`sanitizeErrorMessage()` per the repo-wide error-sanitization rule (`docs/security/ERROR_SANITIZATION.md`). ### Authentication -All six endpoints require authentication via `isAuthenticated()` +All Radar endpoints require authentication via `isAuthenticated()` (`src/shared/utils/apiAuth.ts`) — a dashboard session cookie or a management-scoped API key, the same gate that protects the rest of `/api/settings/*`. The flag-off `404` check always runs **before** the auth check, so an install with `RADAR_ENABLED` diff --git a/open-sse/mcp-server/README.md b/open-sse/mcp-server/README.md index 1ef5f8aa5f..cf3d5ce748 100644 --- a/open-sse/mcp-server/README.md +++ b/open-sse/mcp-server/README.md @@ -1,6 +1,6 @@ # OmniRoute MCP Server -> **Model Context Protocol server** that exposes OmniRoute's gateway intelligence as **104 tools** for AI agents. +> **Model Context Protocol server** that exposes OmniRoute's gateway intelligence as **109 tools** for AI agents. > > **Source of truth for the full tool catalog and REST surface:** [`docs/frameworks/MCP-SERVER.md`](../../docs/frameworks/MCP-SERVER.md). This README focuses on architecture, configuration, and integration examples; the catalog below is a summary subset. @@ -20,7 +20,7 @@ The MCP Server allows any AI agent (Claude Desktop, Cursor, VS Code Copilot, cus ┌──────────────────────────────────────────────────────────────────┐ │ OmniRoute MCP Server │ │ ┌──────────────┐ ┌─────────────────┐ ┌────────────────────┐ │ -│ │ Scope │ │ 104 MCP Tools │ │ Audit Logger │ │ +│ │ Scope │ │ 109 MCP Tools │ │ Audit Logger │ │ │ │ Enforcement │──│ (core + memory │──│ (SHA-256/SQLite) │ │ │ │ │ │ + skills + …) │ │ │ │ │ └──────────────┘ └────────┬────────┘ └────────────────────┘ │ @@ -120,18 +120,23 @@ omniroute --mcp ## Tool Reference -### Phase 1: Essential Tools (8) +### Phase 1: Essential Tools (13) | # | Tool | Scopes | Description | | --- | ------------------------------- | --------------------- | -------------------------------------------------------------------------- | -| 1 | `omniroute_get_health` | `read:health` | Gateway health, uptime, memory, circuit breakers, rate limits, cache stats | -| 2 | `omniroute_list_combos` | `read:combos` | List all combos (model chains) with strategies and optional metrics | -| 3 | `omniroute_get_combo_metrics` | `read:combos` | Performance metrics for a specific combo | -| 4 | `omniroute_switch_combo` | `write:combos` | Activate or deactivate a combo for routing | -| 5 | `omniroute_check_quota` | `read:quota` | Remaining API quota per provider with token health status | -| 6 | `omniroute_route_request` | `execute:completions` | Send a chat completion through intelligent routing | -| 7 | `omniroute_cost_report` | `read:usage` | Cost report by period (session/day/week/month) with per-provider breakdown | -| 8 | `omniroute_list_models_catalog` | `read:models` | List all available models across providers with capabilities and pricing | +| 1 | `omniroute_tool_search` | `read:tools` | Discover tools from the registered MCP catalog | +| 2 | `omniroute_get_health` | `read:health` | Gateway health, uptime, memory, circuit breakers, rate limits, cache stats | +| 3 | `omniroute_list_combos` | `read:combos` | List all combos (model chains) with strategies and optional metrics | +| 4 | `omniroute_get_combo_metrics` | `read:combos` | Performance metrics for a specific combo | +| 5 | `omniroute_switch_combo` | `write:combos` | Activate or deactivate a combo for routing | +| 6 | `omniroute_create_combo` | `write:combos` | Create a validated combo through the existing combo API | +| 7 | `omniroute_check_quota` | `read:quota` | Remaining API quota per provider with token health status | +| 8 | `omniroute_route_request` | `execute:completions` | Send a chat completion through intelligent routing | +| 9 | `omniroute_cost_report` | `read:usage` | Cost report by period (session/day/week/month) with per-provider breakdown | +| 10 | `omniroute_list_models_catalog` | `read:models` | List all available models across providers with capabilities and pricing | +| 11 | `omniroute_radar_catalog` | `read:radar` | Read the local signed Radar catalog with provider/family filters | +| 12 | `omniroute_web_search` | `execute:search` | Search the web through configured search providers | +| 13 | `omniroute_web_fetch` | `execute:search` | Fetch web content through configured fetch providers | ### Phase 2: Advanced Tools (8) diff --git a/scripts/check/check-docs-counts-sync.mjs b/scripts/check/check-docs-counts-sync.mjs index c0e4cf83f6..01ad1aeef1 100644 --- a/scripts/check/check-docs-counts-sync.mjs +++ b/scripts/check/check-docs-counts-sync.mjs @@ -147,9 +147,10 @@ function readCodeFacts() { 'import {pluginTools} from "./open-sse/mcp-server/tools/pluginTools.ts";', 'import {notionTools} from "./open-sse/mcp-server/tools/notionTools.ts";', 'import {obsidianTools} from "./open-sse/mcp-server/tools/obsidianTools.ts";', + 'import {localCorpusTools} from "./open-sse/mcp-server/tools/localCorpusTools.ts";', 'import {compressionTools} from "./open-sse/mcp-server/tools/compressionTools.ts";', "const cols={MCP_TOOLS,memoryTools,skillTools,agentSkillTools,githubSkillTools,poolTools,", - "gamificationTools,pluginTools,notionTools,obsidianTools,compressionTools};", + "gamificationTools,pluginTools,notionTools,obsidianTools,localCorpusTools,compressionTools};", "const sc=new Set();", "for(const col of Object.values(cols))for(const t of Object.values(col))", "for(const x of (t?.scopes||[]))sc.add(x);", @@ -313,7 +314,7 @@ export function buildChecks() { // total ("33 tools (25 CLI Code's …)") are not the MCP aggregate // per-module rows read "… tool definitions (N tools" / "… management tools // (N tools" — the word tool(s)/definitions sits right before the paren. The - // aggregate ("MCP Server (104 tools", "all 104 tools") never does. + // aggregate ("MCP Server (109 tools", "all 109 tools") never does. skipBefore: /(tools?|definitions?)\s*\(\s*$/i, skipAfter: /^\s*\(\d+ CLI/, }, diff --git a/tests/unit/check-docs-counts-sync.test.ts b/tests/unit/check-docs-counts-sync.test.ts index 27deae3057..7f7aaaaffd 100644 --- a/tests/unit/check-docs-counts-sync.test.ts +++ b/tests/unit/check-docs-counts-sync.test.ts @@ -148,7 +148,7 @@ test("free-tier gate passes when a file carries no headline at all", () => { // --- Generic numeric-claim gate (engines / MCP tools / scopes / CLI) -------- // Extends the same drift guard to the counts that silently drifted in v3.8.49: -// 11→12 engines, 94→104 MCP tools, 30→31 scopes, 26→33 CLI tools. +// 11→12 engines, 94→109 MCP tools, 30→33 scopes, 26→33 CLI tools. import { makeNumberClaimValidator } from "../../scripts/check/check-docs-counts-sync.mjs"; const makeValidator = makeNumberClaimValidator as ( @@ -157,19 +157,19 @@ const makeValidator = makeNumberClaimValidator as ( ) => (content: string) => { ok: boolean; detail: string }; test("MCP-tools gate accepts the aggregate and rejects a stale one", () => { - const v = makeValidator(104, { + const v = makeValidator(109, { what: "MCP tools", pattern: /(\d+) tools/gi, skipBefore: /(tools?|definitions?)\s*\(\s*$/i, skipAfter: /^\s*\(\d+ CLI/, }); - assert.equal(v("MCP Server (104 tools)").ok, true); - assert.equal(v("with 104 tools total").ok, true); + assert.equal(v("MCP Server (109 tools)").ok, true); + assert.equal(v("with 109 tools total").ok, true); assert.equal(v("MCP Server (94 tools)").ok, false); }); test("MCP-tools gate ignores per-module counts and the CLI catalog total", () => { - const v = makeValidator(104, { + const v = makeValidator(109, { what: "MCP tools", pattern: /(\d+) tools/gi, skipBefore: /(tools?|definitions?)\s*\(\s*$/i,
InterfaceEndpoint / commandUse it for
🧰 MCP (stdio)omniroute --mcpPlug into Claude Desktop, Cursor, any MCP client
🌊 MCP (HTTP)/api/mcp/streamRemote MCP — 105 tools, 31 scopes, full audit trail
🌊 MCP (HTTP)/api/mcp/streamRemote MCP — 109 tools, 33 scopes, full audit trail
📡 MCP (SSE)/api/mcp/sseStreaming MCP transport
🤝 A2A/.well-known/agent.jsonAgent-to-agent, JSON-RPC 2.0 + SSE, 6 skills
🌐 REST API/v1/*OpenAI-compatible — chat, embeddings, images, audio, OCR
DocumentDescription
API ReferenceAll endpoints with examples
OpenAPI SpecOpenAPI 3.0 specification
MCP Server104 MCP tools, IDE configs, Python/TS/Go clients
MCP Server109 MCP tools, IDE configs, Python/TS/Go clients
MCP Server GuideMCP installation, transports, and tool reference
A2A ServerJSON-RPC 2.0 protocol, skills, streaming, task mgmt
A2A Server GuideA2A agent card, tasks, skills, and streaming