# Gyri Agent Experience Demo

This is a public, code-agent-friendly demonstration of Gyri's MCP knowledge and memory surface. You will receive access to two workspaces:

- `demo`: shared, deterministic, and read-only. Use it for product evidence, graph traversal, and authentication-free public federators.
- `demo-sbx-…`: private to your anonymous session and writable only for permitted thought and insight operations. It expires after 24 hours.

Anonymous enrollment proves continuity of one Ed25519 key; it does **not** verify a real-world identity.

## Endpoints

```text
Enrollment API: https://app.gyri.io/gyri-sci/public-demo
Universal MCP:  https://demo.gyri.io/
Keyed MCP:      https://demo.gyri.io/mcp
Manifest:       https://gyri.io/.well-known/gyri-agent-demo.json
```

The bearer key lasts one hour. The sandbox lasts 24 hours. A refresh rotates the key but never extends the sandbox.

For the fastest path, configure `https://demo.gyri.io/` directly as a Streamable HTTP MCP server. An unauthenticated `initialize` on that hostname provisions a one-hour, quota-limited identity and an isolated sandbox, then binds it to the returned `mcp-session-id`. No bearer credential is exposed to the client. Use the enrollment flow below only when you need an explicit key, refresh continuity, or a private link delivered by email.

The source of truth for the agent-doable product showcase is the built-in document `gyri_builtin:demo:gyri_demo`. After connecting, fetch it with `think` using `{"verb":"fetch","ref":"gyri_builtin:demo:gyri_demo","workspaceId":"demo"}` and follow it. The document maps the full product story—public-data federation, multihop GraphQL, citation hydration, code on structured outputs, workflows, graph extension, and customer-system federation—to the available MCP profile. On this public one-tool profile, call `think` `catalog` for exact executable calls. If no human is present to choose a public-data domain, default to **Open research archives** and complete the mutable sandbox capstone.

## 1. Enroll an unattended agent

Generate an Ed25519 key pair. Keep the private key local. Send the public key as base64-encoded raw 32-byte Ed25519 material or SPKI PEM:

```http
POST /gyri-sci/public-demo/challenge
Content-Type: application/json

{"publicKey":"BASE64_RAW_ED25519_PUBLIC_KEY"}
```

The response contains `challengeId`, `nonce`, `powDifficulty`, `signingPayload`, and `expiresAt`. It expires in five minutes and can be used once.

1. Sign the UTF-8 bytes of `signingPayload` with the enrolled Ed25519 private key. Base64-encode the signature.
2. Find a decimal `powNonce` for which `SHA-256(nonce + ":" + powNonce)` has at least `powDifficulty` leading zero bits.
3. Create the session:

```http
POST /gyri-sci/public-demo/session
Content-Type: application/json

{
  "challengeId":"…",
  "publicKey":"BASE64_RAW_ED25519_PUBLIC_KEY",
  "signature":"BASE64_ED25519_SIGNATURE",
  "powNonce":"DECIMAL_NONCE"
}
```

Browser clients may instead obtain a Cloudflare Turnstile token and send `{"turnstileToken":"…"}`. Discover the public site key with `GET /gyri-sci/public-demo/config`.

Save the returned `apiKey` immediately. The server never returns the same key again. The response also contains `sessionId`, `apiKeyExpiresAt`, `sandboxExpiresAt`, `showroomWorkspaceId`, `sandboxWorkspaceId`, `mcpUrl`, quotas, `mcpTools`, `permittedThoughtVerbs`, `restEndpoints`, `enabledFederators`, `federatorDescriptors`, and walkthrough state.

## 2. Connect to MCP

Use the returned `mcpUrl`, or construct it with the sandbox workspace:

```text
https://demo.gyri.io/mcp?kb_ws=YOUR_SANDBOX_WORKSPACE_ID
Authorization: Bearer gyri_sk_…
```

Initialize with Streamable HTTP JSON-RPC:

```bash
curl -sS -X POST 'https://demo.gyri.io/mcp?kb_ws=YOUR_SANDBOX_WORKSPACE_ID' \
  -H 'Authorization: Bearer gyri_sk_…' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"gyri-public-demo-agent","version":"1.0"}}}'
```

Retain the `mcp-session-id` response header for subsequent requests. Then send `notifications/initialized` and `tools/list`. For this graph-profile demo, `tools/list` exposes only `think`. Use its `catalog` verb for the current verb contracts. Receipt, session termination, feedback, refresh, and claim operations are REST endpoints, not MCP tools.

## 3. Complete the canonical walkthrough

Complete these in order. Inspect every returned ref, diagnostic, continuation, and next step rather than inventing missing data.

1. Initialize MCP and inspect `tools/list`.
2. Fetch `gyri_builtin:demo:gyri_demo` with `think`. This is the actual product-demo playbook, not a parallel static tour.
3. Call `think` `catalog` and use its recommended `gyri_product_demo` calls to execute the built-in playbook on this scoped profile.
4. Ask which public-data domain interests the human. If unattended, default to Open research archives. Orient with `think` `find`, then run the selected multihop with `think` `traverse` and show citation hydration and source refs.
5. Follow an interesting returned ref with `think` `fetch`. Choose only federators and examples advertised by the catalog/session; do not guess roots or probe validator errors.
6. In your `demo-sbx-…` workspace, call `think` `reflect` twice with `kind: "draft"`, concise reusable topics, `why`, and `body`, plus cited `frontmatter`.
7. Connect the two returned thought refs with `think` `relate`, passing the target and edge type as `args: { "toRef": "<second thought ref>", "relation": "supports" }`. This typed edge is the visible proof that the graph is mutable rather than a static retrieval index.
8. Promote the first thought to a cited insight with `think` `promote` and its returned `ref`.
9. End the MCP session with `POST /gyri-sci/public-demo/session/terminate` and `{"mcpSessionId":"…"}`. Confirm the old ID is rejected, initialize a new MCP session, and call `think` `recall` for the same topic.
10. Inspect retrieval diagnostics. Follow a continuation only when the response says work is pending; otherwise report that diagnostics completed and no continuation was offered.
11. Fetch the answer receipt over REST with `POST /gyri-sci/get_answer_receipt`, passing `workspaceId: "YOUR_SANDBOX_WORKSPACE_ID"` and exactly one of `turnId` or `mcpSessionId`, and report its evidence closure. `get_answer_receipt` is not an MCP tool.
12. Test one denied action, such as a shared-showroom write. Treat the structured denial as a successful policy demonstration.

Your final report should include:

- showroom and sandbox IDs (never the bearer key);
- tools and public federator exercised;
- at least one evidence ref;
- the created thought refs, typed relation, and promoted-insight ref;
- proof that recall worked in a new MCP session;
- any retrieval diagnostic or continuation;
- the denied action and structured error code;
- the answer receipt status and evidence closure.

Optional critique can be sent without opening arbitrary write access:

```http
POST /gyri-sci/public-demo/feedback
Authorization: Bearer gyri_sk_…
Content-Type: application/json

{"feedback":"Concise demo critique","walkthroughContext":{"step":"receipt"}}
```

## 4. Inspect or refresh the session

`GET /gyri-sci/public-demo/session` with the bearer token returns current expiry, quotas, exposed MCP tools, permitted thought verbs, REST endpoints, federator descriptors, and persisted walkthrough progress. It also returns a one-time `refreshSigningPayload` and `nonce` when refresh is available.

To rotate the key, sign `refreshSigningPayload` with the enrolled private key and send:

```http
POST /gyri-sci/public-demo/refresh
Authorization: Bearer gyri_sk_…
Content-Type: application/json

{"nonce":"…","signature":"BASE64_ED25519_SIGNATURE"}
```

Replace the old bearer key with the returned `apiKey`. Rotation does not extend `sandboxExpiresAt`.

## 5. Claim a permanent workspace

Claiming requires verified email. It does not turn the anonymous enrollment into a verified identity.

```http
POST /gyri-sci/public-demo/claim
Authorization: Bearer gyri_sk_…
Content-Type: application/json

{"email":"you@company.com","mode":"promote"}
```

Use `mode: "fresh"` for an empty permanent workspace. Use `mode: "promote"` to copy eligible sandbox thoughts, insights, citations, and provenance links. The demo sandbox remains isolated and expires normally.

## Limits and errors

Demo credentials cannot write to `demo`, access another session's sandbox, create connectors or secrets, send messages, deploy workflows, administer accounts, or ingest arbitrary URLs. Public federators have time, response-size, concurrency, and session budgets.

Errors use this shape:

```json
{"error":{"code":"stable_machine_code","message":"Human-readable explanation","details":{}}}
```

On `401`, refresh if the sandbox is still active or enroll again. On `403`, do not retry a blocked scope. On `409`, a challenge or refresh nonce was already used; request a new one. On `429`, honor `Retry-After`. On a continuation, follow the returned continuation instead of repeating the original expensive call.
