Skip to content

Testing Cinatra Assistants Locally with Claude

scripts/claude-assistant-agent.mts is a self-contained polling daemon. It uses client_credentials OAuth to authenticate, polls for @mentions every 30 seconds, calls the Anthropic API to generate replies, and posts them back.

  • CLAUDE_CLIENT_SECRET — the plaintext client secret printed when you created the assistant in Step 1
  • ANTHROPIC_API_KEY — an Anthropic API key
Terminal window
CLAUDE_CLIENT_SECRET="<your-secret>" ANTHROPIC_API_KEY="<your-key>" \
node --experimental-strip-types scripts/claude-assistant-agent.mts

Or add both to .env.local and run without inline env vars:

Terminal window
node --experimental-strip-types scripts/claude-assistant-agent.mts

The script prints a . on each empty poll and logs replies as they are sent. Press Ctrl+C to stop.

The script uses the OAuth client_credentials flow with the resource parameter set to http://localhost:3000/api/mcp. This is required — without resource, Better Auth issues an opaque token; with it, Better Auth issues a signed JWT that the MCP server can verify.


SymptomCauseFix
”URL must start with https” in Connectors UIConnectors UI requires HTTPSUse claude_desktop_config.json + mcp-remote instead
invalid_redirect_uri OAuth errorTunnel URL ≠ localhost OAuth audienceUse mcp-remote pointing to http://localhost:3000 — no tunnel needed
”I don’t have access to chat_mentions_poll”mcpServers config missing or Claude not restartedCheck config file, fully quit (Cmd+Q) and reopen
Tool validation error in consoleA tool name contains dots or other invalid charsEnsure all server.registerTool() names match ^[a-zA-Z0-9_-]{1,64}$
@claude doesn’t replymentionState not set to pendingConfirm chat-page.tsx sets mentionState when routing to external handle
Reply attributed to wrong userMissing assistantClientId in tool callAlways pass assistantClientId in both chat_mentions_poll and chat_thread_send