Skip to main content
Glama

createProfile

Create a new Nostr profile with display name, bio, picture, and other metadata to establish identity on the decentralized social network.

Instructions

Create a new Nostr profile (kind 0)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameNoDisplay name
aboutNoBio / about text
pictureNoProfile picture URL
nip05NoNIP-05 identifier
lud16NoLightning address
bannerNoBanner image URL
websiteNoWebsite URL
privateKeyNoPrivate key (nsec or hex). Optional when NOSTR_BUNKER_URI is configured.
relaysNoRelays to publish to

Implementation Reference

  • The main handler function for creating a Nostr profile.
    export async function createProfile(params: z.infer<typeof createProfileSchema>) {
      const { privateKey, relays, ...fields } = params;
      return buildAndPublishProfile(fields, privateKey, relays);
    }
  • Zod schema defining the input parameters for creating a profile.
    export const createProfileSchema = z.object({
      name: z.string().optional().describe('Display name'),
      about: z.string().optional().describe('Bio / about text'),
      picture: z.string().optional().describe('Profile picture URL'),
      nip05: z.string().optional().describe('NIP-05 identifier'),
      lud16: z.string().optional().describe('Lightning address'),
      banner: z.string().optional().describe('Banner image URL'),
      website: z.string().optional().describe('Website URL'),
      privateKey: z.string().optional().describe(privateKeyDesc),
      relays: z.array(z.string()).optional().describe('Relays to publish to'),
    });
  • src/index.ts:89-91 (registration)
    Registration of the createProfile MCP tool.
    server.tool('createProfile', 'Create a new Nostr profile (kind 0)', createProfileSchema.shape, async (params) => {
      return textResult(await createProfile(params));
    });
  • Helper function that constructs and publishes the Nostr metadata event.
    async function buildAndPublishProfile(
      fields: Record<string, string | undefined>,
      privateKey: string | undefined,
      relays: string[] | undefined,
    ): Promise<{ event: VerifiedEvent; published: { successes: string[]; failures: string[] } }> {
      const content: Record<string, string> = {};
      for (const [k, v] of Object.entries(fields)) {
        if (v !== undefined) content[k] = v;
      }
    
      const template: EventTemplate = {
        kind: KINDS.METADATA,
        content: JSON.stringify(content),
        tags: [],
        created_at: Math.floor(Date.now() / 1000),
      };
    
      let signed: VerifiedEvent;
      if (isBunkerMode()) {
        signed = await signEventWithBunker(template);
      } else {
        if (!privateKey) throw new Error('privateKey is required when NOSTR_BUNKER_URI is not configured');
        const sk = normalizePrivateKey(privateKey);
        signed = finalizeEvent(template, sk);
      }
    
      const result = await publishEvent(signed, relays ?? DEFAULT_RELAYS);
      return { event: signed, published: result };
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jorgenclaw/nostr-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server