# CrowdListen Agent Reference

CrowdListen exposes one MCP contract with three tools: `recall`, `analyze`, and `ingest`.

## Setup

```bash
npx -y -p @crowdlisten/harness crowdlisten-harness login
```

Login stores a CrowdListen session locally and configures supported agent clients. Restart the client after setup.

Login and MCP startup do not create an additional API key. Existing saved keys remain unchanged; scoped script keys are managed separately in the web app.

Generated MCP configuration pins the package version that performed setup. Standard CrowdListen npx entries are updated while custom commands and their settings are preserved. Publish that version before distributing its setup flow; a local build is not an installed customer release.

Long-running stdio clients resolve the current Supabase session before each tool request. On-demand refresh is serialized across local processes; conditional credential updates and atomic replacement prevent stale cooperating writers from undoing logout or a later login. Each process is bound to its original login generation; logout, a different account or a later login requires restarting the connection. Auth failure happens before the operation is submitted and does not replay writes automatically. Upgrade/restart all writers together and see [session coordination and recovery](docs/AUTH_SESSIONS.md) for busy errors, lock recovery and the boundary between local logout and server revocation.

Verify access with `recall({mode: "connection"})`, then select an entity or project and repeat with its ID. The free check returns the verified user session, current scope/permissions and bounded source/finding/history read checks. `read_verified` does not mean browser collection, write persistence or analysis execution was tested. `unavailable` requires remediation; never treat it as a connected/ready result. The matching backend must expose `GET /agent/v1/connection`; the public tool surface remains three tools.

Manual stdio configuration:

```json
{
  "crowdlisten": {
    "command": "npx",
    "args": ["-y", "-p", "@crowdlisten/harness", "crowdlisten-harness"]
  }
}
```

The package also has a local Streamable HTTP transport:

```bash
npx -y -p @crowdlisten/harness crowdlisten-harness serve
```

It exposes `POST /mcp`, `GET /mcp`, `DELETE /mcp`, and `GET /health` on port 3848. Authenticated calls require a valid CrowdListen session token. The hosted `mcp.crowdlisten.com` deployment is not documented as available until its production health check passes.

## Tools

### `recall`

Search or inspect stored CrowdListen data.

```text
recall({ query: "pricing complaints" })
recall({ mode: "entities" })
recall({ mode: "workspaces" })
recall({ mode: "projects" })
recall({ mode: "projects", project_id: "uuid-here", record_type: "documents", record_id: "document-uuid" })
recall({ mode: "insights", entity_name: "Acme" })
recall({ mode: "actions", entity_id: "uuid-here" })
recall({ mode: "intelligence", entity_name: "Acme", window_days: 30 })
recall({ mode: "content", entity_name: "Acme", query: "pricing" })
```

Modes: `search`, `entities`, `workspaces`, `projects`, `insights`, `actions`, `intelligence`, and `content`. Actions include evidence, workflow state, and any saved organization execution plan with labeled projected reach and impact.

Entity recall uses the same authenticated entity API as the browser. `recall({mode: "entities", workspace_id})` optionally filters by workspace; omitting it lists currently accessible personal and shared entities. Returned `config`, `platforms` and `official_channels` preserve saved source choices, schedule and tracked accounts, including empty selections. They are configuration, not proof of successful collection. Revoked membership removes shared entities from subsequent reads. This reader requires the matching backend and `20260912045630_shared_entity_configuration.sql` migration; no hosted rollout is implied.

Project recall uses the same caller-scoped SQL reader as the human page. Preserve `next_cursor` unchanged with the same filters; original content requires `include_content` or a typed `record_id`. Retain partial warnings and unavailable references. Legacy research remains unreviewed. See [project record access and pagination](docs/PROJECT_RECORDS.md).

Action filters include `workflow` and `research_opportunity`. A research opportunity is an inferred possibility to investigate, not an explicit customer request. Generated action `last_seen_at` comes from source publication time and can be null; `payload.evidence_timing` explains seven-day stored-source comparisons, missing dates and sampled-volume limitations. Processing timestamps do not establish evidence freshness.

Versioned shared knowledge adds `knowledge`, `knowledge_source`, `knowledge_changes`, and `knowledge_context` modes. Start with `recall({mode: "knowledge", entity_id})` to reuse generated findings and agent-authored syntheses under the same versioned record contract. Exact quotations, interpretations and legacy-unverified snippets are distinct; an agent revision is preserved during automatic refresh and remains unreviewed. List original sources with `recall({mode: "knowledge_source", entity_id})`; add `content_id` for full current text or `source_revision_id` for a captured revision. Read an insight by `insight_id`, optionally at a historical `revision`. Use `knowledge_changes` with the last processed `after` cursor to resume across sessions. All these reads use the scoped API, including shared entities.

For a bounded current context pack, use `recall({mode: "knowledge_context", entity_id, max_chars: 16000})`. Inspect omission flags, unresolved evidence and `next_offset`; follow returned insight IDs/revisions to retrieve full records. Context is derived from canonical findings and exact snapshots. It does not overwrite stored notes or confer review approval.

For complete unassigned personal originals, use `recall({mode: "knowledge_source", personal: true})`, then add a returned `content_id`. Add `acquisition_history: true` for provider snapshots. Personal scope is caller-owned only and cannot include entity/project IDs or cited source revision IDs. Canonical finding/context/change modes still require an entity or project. See the record contract for the required analyzer capture migration and local verification boundary.

### `analyze`

Research product questions from stored customer and market evidence or bounded live discovery.

```text
analyze({ question: "What do users think about pricing?" })
analyze({ question: "What does this evidence support?", entity_id: "entity-uuid", content_ids: ["source-uuid"], request_id: "stable-request-key" })
analyze({ question: "Compare X vs Y", search_mode: "multi_source", platforms: ["reddit", "twitter"] })
analyze({ action: "start", question: "Where does onboarding fail?", entity_id: "uuid-here", platforms: ["reddit", "web"] })
analyze({ action: "status", job_id: "research-job-uuid" })
```

The default `action: "run"` queues durable analysis research. Persist `analysis_id` and `job_id`; disconnecting or timing out does not cancel the job. Inspect `action: "status"` or reconnect to the saved analysis. Supply `request_id` for retry safety: unchanged inputs and the same key return the same job, while changed reuse conflicts. `action: "start"` uses the same durable capture and canonical finding publication as run, with entity-configured discovery plus stored originals. It returns both job and analysis IDs. `request_id` also makes start retries stable; changed inputs conflict.

For streamed research, inspect `data.research_receipt.complete`, `errors`, collection coverage and the synthesis sample before using the finding. A completed analysis means its result was saved, not that collection was exhaustive. Provider summaries are not original customer quotations. Classifications and synthesis remain unreviewed; source counts do not measure unique customers or market prevalence. Interrupted/error-only streams return MCP errors, with analysis/job IDs when available. Timeout errors mean observation stopped; inspect the saved job before starting another run. Use `ingest(destination: "insight", ...)` for versioned findings with exact evidence citations; entity and project durable runs publish validated findings automatically and return their IDs in the receipt. A run with both IDs retains its entity finding destination. Knowledge reads/writes require exactly one entity or project ID. Project findings require migration `20260911234228_project_knowledge_scope.sql` and matching backend/clients.

### `ingest`

Save curated knowledge, submit feedback observations, or explicitly capture approved entity evidence from an agent or connected tool.

```text
ingest({ title: "Research Summary", content: "## Findings\n...", tags: ["research"] })
ingest({ observations: [{ content: "Need CSV export", observation_type: "feature_request" }] })
ingest({ destination: "evidence", entity_id: "uuid-here", title: "Renewal workflow", content: "...", source_platform: "codex", metadata: { outcome: "approved" } })
ingest({ destination: "execution", action_id: "action-uuid", executor_platform: "codex", approved_for_execution: true, steps: ["Prepare the approved segment"] })
ingest({ destination: "execution", execution_id: "execution-uuid", execution_status: "completed", step_results: [{ step: "Prepare the approved segment", status: "completed", result: "Prepared 12 accounts" }], outcome_summary: "Prepared 12 accounts; nothing was sent", review_status: "approved", training_scopes: ["internal_harness"] })
```

Curated knowledge goes through `POST /agent/v1/context/save` into `pages`. Evidence ingestion goes through `POST /agent/v1/ingest/content` and then runs the canonical persisted entity sweep, returning its terminal run ID and statistics. Execution ingestion creates or updates an Action-linked execution record; creation requires explicit approval, and training portability requires both an owner-approved persisted scope and a caller allowlist. Capturing agent conversations is opt-in; send only approved workflow evidence and include provenance/sensitivity metadata. Recall search uses `GET /agent/v1/context/recall`.

Observation ingestion requires `project_id` with a user session. Each item's non-null `entity_id` overrides the top-level default, then the connector default; all supplied scopes must be authorized in the project's workspace. Include per-item `source_platform`, a provider `source_id` qualified by account/channel, and original `metadata` (author, source URL, publication time). The API returns ordered saved observation IDs with `accepted`, `processing_status` and `research_job_id`, plus legacy submitted/duplicate counts. Retry an unchanged payload to recover the same IDs after a lost response. Changed text or metadata creates a new snapshot of the origin, not an additional unique customer. Missing provider identity is explicitly `snapshot_fallback`; indistinguishable anonymous reports can match. Requires migration `20260912014512_observation_source_identity.sql` and the matching backend. Local protocol tests do not establish hosted or installed-agent readiness.

## Workflow skills

For canonical synthesis writeback, use `ingest({destination: "insight", entity_id, request_id, expected_revision: 0, title, summary, evidence: [{content_id, quote, relation: "supports"}]})`. Reuse the unchanged request ID on retry. To edit, include `insight_id`, a new request ID and the revision just read. Save actual quotations; a summary is not independent evidence or human approval. See [the full record contract](docs/KNOWLEDGE_RECORDS.md) for bounds, conflicts, original source retrieval and rollout requirements.

The package includes ten methodology files that compose the same three tools:

- `audience-research`
- `competitive-analysis`
- `collect-sources`
- `hackernews-research`
- `instagram-research`
- `operate-from-customer-context`
- `reddit-research`
- `tiktok-analyzer`
- `twitter-research`
- `youtube-research`

They do not add MCP tools or change the public tool contract.

Agent-guided extraction uses `recall({mode: "collection_plan", entity_id})`, followed by the customer's authorized browser/source tools. Save structured original batches and separate comments with `ingest({destination: "sources", entity_id, sources, collection_run_id, collection_scope, coverage_state})`. Capture returns acknowledged original IDs and does not start synthesis. Save attempted/blocked channel coverage separately with `ingest({destination: "coverage", entity_id, coverage})`; analyze returned IDs with `search_mode: "user_only"`. See [Collect sources](skills/collect-sources/SKILL.md). Product and competitor scopes remain separate. This requires the matching backend/harness rollout; local tests are not live OpenClaw or hosted extraction proof.

## Supported CLI commands

OpenClaw requires explicit workspace setup after login: `crowdlisten-harness setup openclaw /absolute/path/to/workspace`. It installs a managed skill and pinned mcporter configuration without editing account/provider settings or other tools. Read [OpenClaw setup](docs/OPENCLAW.md), start a new client session, and verify actual connection/collection. This is not part of automatic five-client configuration.

```text
login
login --token <access_token> <refresh_token>
logout
whoami
setup
setup openclaw /absolute/path/to/workspace
serve
context
setup-context
help
```

## Optional action recall

`recall({mode: "actions", entity_id, limit: 50, offset: 0})` reads optional downstream workflows. Follow `next_offset` with the same filters until null; pagination is live. Unknown impact/urgency are null. `knowledge_ref` identifies the exact finding revision behind an action, and evidence retains quote spans, source revisions, supporting/counter/context relations, attribution and unavailable originals. Multiple quotes from the same original are not independent sources.

Explicit-entity durable research returns `research_receipt.actions` alongside canonical findings after one atomic publication. That requires migration `20260911193451_atomic_action_projection.sql` and the matching backend. Entity research uses this same publication transaction. Manual workflow creation remains a separate path. A saved action or plan is not a reviewed product decision. The primary CrowdListen flow is source connection/import, cross-platform analysis and cited findings; execution planning is optional.

Entity-scoped live research now freezes the relevant saved source configuration when a new job is accepted. Omit `platforms` to inherit saved settings; an explicit empty array disables new discovery while existing entity originals remain available. Unchanged-key retries retain the accepted settings, and a new request key uses current settings. The shared executor collects bounded keyword results and configured account feeds from selected platforms, preserving omitted/unresolved targets, provider errors, full originals and exact citations. Account roles are declared relationships, not verified customer identity. This requires the matching 16C backend and preceding configuration/research migrations; local tests do not establish hosted provider success.

Entity start requires migration `20260911212012_unified_entity_research.sql` and matching backend. Shared viewers can inspect status and recall the same versioned finding/originals. Local protocol verification uses synthetic providers and fixed test identities; it does not establish live-account or installed-agent application readiness.

## Shared company skills and routines

Use `recall` modes `skills`, `routines`, and `skill_runs` with entity_id. Save the full skill list with `ingest` destination `skills`, providing the last-read `expected_skills`; conflicts require rereading and merging. Run one hosted saved skill with `analyze({action:"skill", entity_id, skill_id, request_id})`, then inspect status. Configure or pause a routine with `ingest` destination `routine`, its latest revision and an explicit per-run charge limit. Enable recurring paid execution only when the user requested it. Own-agent reasoning reads shared instructions/originals and saves exact-cited findings without calling hosted analyze. [Full contract and release requirements](docs/SAVED_SKILLS.md).
