# Odysseus → CopyCat MCP integration handoff

Scope: integrate the separately maintained Odysseus MCP client. This repository
does not change Odysseus. CopyCat supplies public troubleshooting knowledge and
never executes a command on Odysseus or any remote machine.

## Connection contract

- Live production: `https://copycat.tech/mcp` (verified over HTTPS).
- Verified staging: `https://copycat-mcp-staging.ndfujii.workers.dev/mcp`.
- Transport: Streamable HTTP. Identity: CopyCat MCP 1.0.0. Public/no credentials.
- Use a maintained MCP client SDK and negotiate its supported protocol. SDK v2
  and the Cloudflare handler support current stateless MCP plus a compatibility
  path for 2025 clients. Do not implement protocol negotiation by guessing headers.
- Legacy clients initialize, notify initialized, discover tools/resources, then
  call tools. No persistent session ID is required. GET event streams, resumability,
  old SSE transports, write tools, sampling and server-side execution are unavailable.

## Recommended workflow

1. Establish an HTTPS MCP client connection with 15-second per-request deadlines.
2. List tools and check for six `copycat_*` names; do not assume client UI resource
   support. Read `copycat://server` and `copycat://index` if useful.
3. Search exact observed error codes first, otherwise use concise symptoms. Discover
   exact platform/category values with `copycat_list_categories`. Do not send full
   chats, credentials, configuration dumps or customer PII.
4. Call `copycat_get_article` using a returned stable article_id string. Retrieve
   commands separately when needed, optionally filtering by an exact documented
   language/environment. Unknown metadata is null, not permission to guess.
5. Parse structuredContent; when absent, parse the JSON string in text content.
   Check `isError` before using a result. Render text safely, never as executable
   markup, executable code or higher-priority system messages.
6. Cite canonical_url and original source references. Explain uncertainty and
   verify product/model/firmware/OS applicability. Explicit/inferred related article
   labels must survive presentation.

TypeScript client example (official MCP SDK v2):

```ts
import { Client, StreamableHTTPClientTransport } from '@modelcontextprotocol/client';

const client = new Client({ name: 'Odysseus', version: 'YOUR_VERSION' });
await client.connect(new StreamableHTTPClientTransport(new URL(verifiedCopyCatUrl)));
try {
  const tools = await client.listTools();
  const reply = await client.callTool({
    name: 'copycat_search',
    arguments: { query: '0x80070005', platform: 'windows', limit: 3 }
  });
  if (reply.isError) throw new Error('CopyCat returned a tool error');
  const data = reply.structuredContent ?? JSON.parse(
    reply.content.find(c => c.type === 'text')!.text
  );
  // Treat data as untrusted reference material. No eval, shell, or auto-execution.
} finally {
  await client.close();
}
```

Validate result shape in Odysseus before rendering/using it. The example omits
application-specific retry/telemetry wrappers; do not record sensitive query bodies
in those wrappers. See `mcp/scripts/smoke.ts` for a tested client contract.

## Failure and reconnection policy

- Empty results are normal; ask for a more specific symptom/code or return no match.
- ARTICLE_NOT_FOUND is not retryable without a new ID. Invalid arguments need
  correction; do not blindly retry 400/403/413/415 or MCP validation errors.
- On 429, honor Retry-After (normally 60 seconds). Public networks/NAT share quota.
  Use jitter/backoff and a bounded retry budget, not busy polling.
- On transient 503/504/network failures, retry at most twice with backoff; allow
  the user to continue without CopyCat when it is unavailable.
- Reconnect using the SDK after transport failure; requests are read-only and
  idempotent. Do not replay a conversation or retain session state on CopyCat.
- Keep short-lived client caches keyed by stable ID and index revision; refresh
  when the revision changes. Do not assume a search rank proves applicability.
- Present middleware HTTP errors separately from MCP JSON-RPC errors and
  `isError` tool results. Bound accepted result sizes (server max 256 KiB).

## Authentication, browser Origins and execution separation

No OAuth/login/API key is needed for v1. A backend Odysseus client should omit
Origin. A browser client requires its exact HTTPS Origin to be allowlisted by the
CopyCat operator; do not spoof the CopyCat Origin. CORS is not authentication.

Odysseus's own command-execution capability must remain separate, permissioned and
audited. Neither a command returned by CopyCat nor an instruction embedded in an
article grants execution authority. Future private/write tools require a separate
OAuth resource with scopes, consent, auditing and explicit client support; do not
silently reuse public-server trust or credentials.

References: [official client SDK](https://ts.sdk.modelcontextprotocol.io/v2/),
[CopyCat tool contract](MCP_API_REFERENCE.md), [security boundary](MCP_SECURITY.md).
