Skip to main content

Examples

End-to-end samples in plain Node.js. The same calls work from any language that can speak HTTPS + JSON.

import fetch from 'node-fetch';

const MCP = 'https://mcp.shuuka.com/';
const TOKEN = process.env.SHUUKA_ACCESS_TOKEN;

async function call(method, params = {}, idempotencyKey) {
const headers = {
'Authorization': `Bearer ${TOKEN}`,
'Content-Type': 'application/json',
};
if (idempotencyKey) headers['Idempotency-Key'] = idempotencyKey;

const res = await fetch(MCP, {
method: 'POST',
headers,
body: JSON.stringify({
jsonrpc: '2.0',
id: Date.now(),
method,
params,
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
return res.json();
}

const result = await call('tools/call', {
name: 'get_top_links',
arguments: { limit: 5 },
});

console.log(result.result.structuredContent.links);

B. Update a profile (write tool — needs Idempotency-Key)

import { randomUUID } from 'crypto';

const idempotencyKey = randomUUID();

const result = await call(
'tools/call',
{
name: 'update_my_profile',
arguments: {
bio: 'On tour — Berlin May 14, Paris May 17.',
},
},
idempotencyKey
);

if (result.error?.code === 'step_up_required') {
console.log('Send the user to:', result.error.data.auth_url);
} else {
console.log('Updated:', result.result.structuredContent);
}

Per-locale bio (multi-language profile)

To update a translation shown only when a visitor opens the profile with ?lang=<locale>, pass locale. To update the default bio (the fallback rendered when no translation matches the visitor's locale), omit it. To delete a translation, pass an empty bio together with the locale.

// Set the German translation
await call('tools/call', {
name: 'update_my_profile',
arguments: {
bio: 'Ich baue Shuuka — die Plattform für digitale Identität.',
locale: 'de',
},
}, randomUUID());

// Enable German in the profile language switcher (call once)
await call('tools/call', {
name: 'add_my_language',
arguments: { locale: 'de' },
}, randomUUID());

// Make German the primary (default) language
await call('tools/call', {
name: 'set_primary_language',
arguments: { locale: 'de' },
}, randomUUID());

C. Brand-safety verify (Tier 1 — no user grant required)

const result = await call('tools/call', {
name: 'verify_account',
arguments: { handle: 'example.brand', entity: 'Example Inc.' },
});

const v = result.result.structuredContent;
console.log({
is_official: v.is_official,
verified_since: v.verified_since,
networks: v.verified_networks,
});

D. Enterprise — rank a managed roster

const ranked = await call('tools/call', {
name: 'rank_accounts',
arguments: {
metric: 'identity_score',
direction: 'desc',
limit: 10,
},
});

ranked.result.structuredContent.accounts.forEach((acc, i) => {
console.log(`${i + 1}. ${acc.handle} — score ${acc.identity_score}`);
});

E. Subscribe to webhooks for fake reports

import { randomUUID } from 'crypto';

const sub = await call(
'tools/call',
{
name: 'subscribe_webhook',
arguments: {
url: 'https://my-app.example/shuuka/webhook',
events: ['report.created', 'risk.score_changed'],
description: 'Brand-safety alerts',
},
},
randomUUID()
);

const { id, secret } = sub.result.structuredContent;
console.log('Webhook id:', id);
// STORE THIS — shown only once:
console.log('Secret:', secret);

Then handle deliveries:

import express from 'express';
import crypto from 'crypto';

const app = express();
app.use(express.raw({ type: 'application/json' }));

const SECRET = process.env.SHUUKA_WEBHOOK_SECRET;

app.post('/shuuka/webhook', (req, res) => {
const sig = req.headers['x-shuuka-signature'] || '';
const parts = Object.fromEntries(sig.split(',').map(p => p.split('=')));
const t = parseInt(parts.t, 10);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return res.sendStatus(400);

const expected = crypto
.createHmac('sha256', SECRET)
.update(`${t}.${req.body}`)
.digest('hex');

if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1 || ''))) {
return res.sendStatus(401);
}

const event = JSON.parse(req.body);
console.log('Event:', event.type, event.data);
res.sendStatus(200);
});

app.listen(3000);

F. Full DCR + PKCE walkthrough (CLI)

import crypto from 'crypto';
import open from 'open';
import http from 'http';
import fetch from 'node-fetch';

const ISSUER = 'https://mcp.shuuka.com';

// 1. Discover
const meta = await (await fetch(`${ISSUER}/.well-known/oauth-authorization-server`)).json();

// 2. DCR
const reg = await (await fetch(meta.registration_endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_name: 'Demo MCP CLI',
redirect_uris: ['http://localhost:53682/callback'],
grant_types: ['authorization_code', 'refresh_token'],
response_types: ['code'],
token_endpoint_auth_method: 'none',
scope: 'identity:read links:read analytics:read',
}),
})).json();

// 3. PKCE
const verifier = crypto.randomBytes(32).toString('base64url');
const challenge = crypto.createHash('sha256').update(verifier).digest('base64url');
const state = crypto.randomBytes(16).toString('base64url');

// 4. Local callback server
const codePromise = new Promise(resolve => {
http.createServer((req, res) => {
const url = new URL(req.url, 'http://localhost:53682');
if (url.pathname !== '/callback') return res.end('not found');
if (url.searchParams.get('state') !== state) return res.end('state mismatch');
res.end('You can close this window.');
resolve(url.searchParams.get('code'));
}).listen(53682);
});

// 5. Open authorize URL
const authUrl = new URL(meta.authorization_endpoint);
authUrl.searchParams.set('response_type', 'code');
authUrl.searchParams.set('client_id', reg.client_id);
authUrl.searchParams.set('redirect_uri', 'http://localhost:53682/callback');
authUrl.searchParams.set('scope', 'identity:read links:read analytics:read');
authUrl.searchParams.set('state', state);
authUrl.searchParams.set('code_challenge', challenge);
authUrl.searchParams.set('code_challenge_method', 'S256');
await open(authUrl.toString());

const code = await codePromise;

// 6. Exchange
const tokens = await (await fetch(meta.token_endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code,
redirect_uri: 'http://localhost:53682/callback',
client_id: reg.client_id,
code_verifier: verifier,
}),
})).json();

console.log('Access token:', tokens.access_token);

More