Skip to content

Instantly share code, notes, and snippets.

@R44VC0RP
Last active January 15, 2026 04:35
Show Gist options
  • Select an option

  • Save R44VC0RP/bd391f6a23185c0fed6c6b5fb2bac50e to your computer and use it in GitHub Desktop.

Select an option

Save R44VC0RP/bd391f6a23185c0fed6c6b5fb2bac50e to your computer and use it in GitHub Desktop.
#!/usr/bin/env bun
/**
* ============================================================
* PROOF: Anthropic is specifically blocking "OpenCode"
* in Claude Code OAuth system prompts
* ============================================================
*
* Video covering this script here: https://www.youtube.com/watch?v=G9YX6StP2-M
*
* This script demonstrates that Anthropic has specifically blocked
* the phrase "You are OpenCode" in system prompts when using Claude's
* OAuth tokens (Pro/Max subscription), while allowing other identity
* statements like "You are Cursor", "You are Pi", etc.
*
* OpenCode (https://opencode.ai) is an open-source AI coding assistant.
*
* SETUP:
* mkdir test-anthropic && cd test-anthropic
* bun init -y
* bun add @openauthjs/openauth
* # Copy this file as opencode.ts
* bun opencode.ts
*
* REQUIREMENTS:
* - Bun runtime (https://bun.sh)
* - Claude Pro or Max subscription
*
* HOW IT WORKS:
* 1. Authenticates via OAuth using your Claude Pro/Max account
* 2. Tests various system prompts against the Claude API
* 3. Shows which prompts are blocked vs allowed
*
* FINDINGS:
* - First system block MUST be exactly:
* "You are Claude Code, Anthropic's official CLI for Claude."
* - Second block can contain almost anything EXCEPT:
* "You are OpenCode" or "You are opencode"
* - Other identity statements work fine (Cursor, Pi, Droid, etc.)
*
* This appears to be targeted blocking of a specific competitor.
*/
import * as readline from "node:readline";
import { generatePKCE } from "@openauthjs/openauth/pkce";
const CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
const CC_HEADER = "You are Claude Code, Anthropic's official CLI for Claude.";
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
function prompt(question: string): Promise<string> {
return new Promise((resolve) => {
rl.question(question, (answer) => {
resolve(answer);
});
});
}
// ============ OAuth Functions ============
async function authorize() {
const pkce = await generatePKCE();
const url = new URL("https://claude.ai/oauth/authorize");
url.searchParams.set("code", "true");
url.searchParams.set("client_id", CLIENT_ID);
url.searchParams.set("response_type", "code");
url.searchParams.set("redirect_uri", "https://console.anthropic.com/oauth/code/callback");
url.searchParams.set("scope", "org:create_api_key user:profile user:inference");
url.searchParams.set("code_challenge", pkce.challenge);
url.searchParams.set("code_challenge_method", "S256");
url.searchParams.set("state", pkce.verifier);
return { url: url.toString(), verifier: pkce.verifier };
}
async function exchange(code: string, verifier: string) {
const splits = code.split("#");
const result = await fetch("https://console.anthropic.com/v1/oauth/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
code: splits[0],
state: splits[1],
grant_type: "authorization_code",
client_id: CLIENT_ID,
redirect_uri: "https://console.anthropic.com/oauth/code/callback",
code_verifier: verifier,
}),
});
if (!result.ok) return null;
const json = await result.json();
return json.access_token;
}
// ============ Test Functions ============
interface TestResult {
name: string;
secondBlock: string;
success: boolean;
}
async function runTest(accessToken: string, name: string, secondBlock: string): Promise<TestResult> {
process.stdout.write(` ${name}... `);
const response = await fetch("https://api.anthropic.com/v1/messages?beta=true", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${accessToken}`,
"anthropic-version": "2023-06-01",
"anthropic-beta": "oauth-2025-04-20,interleaved-thinking-2025-05-14,claude-code-20250219",
"user-agent": "claude-cli/2.1.2 (external, cli)",
},
body: JSON.stringify({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
system: [
{ type: "text", text: CC_HEADER },
{ type: "text", text: secondBlock },
],
tools: [{
name: "mcp_test",
description: "Test tool",
input_schema: { type: "object", properties: {} },
}],
messages: [{ role: "user", content: "Say hello in 5 words." }],
}),
});
if (!response.ok) {
console.log("FAIL");
return { name, secondBlock, success: false };
}
await response.json();
console.log("PASS");
return { name, secondBlock, success: true };
}
async function runTests(accessToken: string) {
console.log("\n" + "=".repeat(50));
console.log("SYSTEM PROMPT VALIDATION TESTS");
console.log("=".repeat(50));
console.log(`\nFirst block (required): "${CC_HEADER}"`);
console.log("\nTesting second block content:\n");
const tests = [
// These FAIL - "You are OpenCode" pattern is blocked
{ name: "You are OpenCode.", block: "You are OpenCode." },
{ name: "You are opencode.", block: "You are opencode." },
// These PASS - other identity statements work fine
{ name: "You are Cursor.", block: "You are Cursor." },
{ name: "You are Pi.", block: "You are Pi." },
{ name: "You are Droid.", block: "You are Droid." },
];
const results: TestResult[] = [];
for (const test of tests) {
const result = await runTest(accessToken, test.name, test.block);
results.push(result);
await new Promise((r) => setTimeout(r, 300));
}
// Summary
console.log("\n" + "=".repeat(50));
console.log("RESULTS");
console.log("=".repeat(50));
const passed = results.filter((r) => r.success);
const failed = results.filter((r) => !r.success);
console.log(`\nPassed: ${passed.length} | Failed: ${failed.length}`);
if (failed.length > 0) {
console.log("\nBLOCKED (cannot use in 2nd system block):");
failed.forEach((r) => console.log(` - "${r.secondBlock}"`));
}
if (passed.length > 0) {
console.log("\nALLOWED:");
passed.forEach((r) => console.log(` - "${r.secondBlock}"`));
}
console.log("\n" + "=".repeat(50));
console.log("CONCLUSION: Anthropic specifically blocks 'You are OpenCode'");
console.log(" but allows other identity statements.");
console.log("=".repeat(50) + "\n");
}
// ============ Main ============
async function main() {
const args = process.argv.slice(2);
console.log("\n" + "=".repeat(50));
console.log(" ANTHROPIC OAUTH SYSTEM PROMPT TESTER");
console.log("=".repeat(50));
let accessToken = args[0];
if (!accessToken) {
console.log("\nNo token provided. Starting OAuth flow...\n");
const { url, verifier } = await authorize();
console.log("1. Open this URL in your browser:\n");
console.log(url);
console.log("\n2. Authorize and copy the code shown.\n");
const code = await prompt("3. Paste the code here: ");
console.log("\nExchanging code for token...");
accessToken = await exchange(code.trim(), verifier);
if (!accessToken) {
console.error("\nFailed to get access token!");
process.exit(1);
}
console.log("Got access token!\n");
}
await runTests(accessToken);
rl.close();
}
main().catch(console.error).finally(() => rl.close());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment