npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, πŸ‘‹, I’m Ryan HefnerΒ  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you πŸ™

Β© 2026 – Pkg Stats / Ryan Hefner

neko-medium-publisher

v1.0.0

Published

🐾 AI-powered Medium publishing with MongoDB logging and TypeScript support

Readme

🐾 @neko-arc/medium-publisher

AI-powered Medium publishing with MongoDB logging and TypeScript support

npm version License: MIT

Publish articles to Medium programmatically with optional MongoDB logging, perfect for AI agents, automation workflows, and content management systems.


✨ Features

  • βœ… TypeScript Native - Full type safety and IntelliSense support
  • βœ… Medium API Integration - Publish articles using official Medium SDK
  • βœ… MongoDB Logging - Optional automatic logging to MongoDB Atlas
  • βœ… CLI Interface - Easy command-line publishing
  • βœ… Multiple Formats - Support for Markdown and HTML
  • βœ… Publish Statuses - Draft, Public, or Unlisted
  • βœ… Tags & Metadata - Full support for tags, canonical URLs, and licenses
  • βœ… AI Integration - Designed for agent-based content generation

πŸ“¦ Installation

npm install -g @neko-arc/medium-publisher

Or as a project dependency:

npm install @neko-arc/medium-publisher

πŸš€ Quick Start

1. Get Medium Integration Token

Visit https://medium.com/me/settings/security

  1. Login to Medium
  2. Go to Settings > Security
  3. Scroll to "Integration tokens"
  4. Enter description: "My Publishing Tool"
  5. Click "Get integration token"
  6. Copy the token

2. Create .env file

# Medium API Credentials
MEDIUM_ACCESS_TOKEN=your_integration_token_here

# MongoDB Atlas Connection (optional)
MONGODB_URI=mongodb+srv://username:[email protected]/
MONGODB_DATABASE=my-database
MONGODB_COLLECTION=medium-publications

3. Publish Your First Article

neko-medium publish \
  --file ./my-article.md \
  --title "My First Article" \
  --status draft \
  --tags "technology,programming"

πŸ’» CLI Usage

Test Connection

neko-medium test

Verify your Medium API credentials and display user information.

Publish Article

neko-medium publish \
  --file <path-to-file> \
  --title "Article Title" \
  [options]

Options:

| Option | Description | Default | |--------|-------------|---------| | -f, --file <path> | Path to markdown or HTML file | Required | | -t, --title <title> | Article title | Required | | -s, --status <status> | public, draft, unlisted | draft | | --format <format> | markdown, html | markdown | | --tags <tags> | Comma-separated tags | "" | | --canonical <url> | Canonical URL | - | | --source <source> | manual, ai-agent, automated | manual | | --generated-by <name> | Generated by (personality/agent) | neko-arc | | --no-mongo | Disable MongoDB logging | - |

List Publications

neko-medium list [--status <status>]

List all publications from MongoDB. Filter by status: public, draft, or unlisted.


πŸ“š Programmatic Usage

TypeScript/JavaScript

import { MediumPublisher } from '@neko-arc/medium-publisher';
import * as dotenv from 'dotenv';

dotenv.config();

async function main() {
  // Initialize publisher
  const publisher = new MediumPublisher({
    accessToken: process.env.MEDIUM_ACCESS_TOKEN!,
    mongoUri: process.env.MONGODB_URI,
    mongoDatabase: 'my-database',
    mongoCollection: 'medium-publications',
    enableMongoLogging: true,
  });

  await publisher.initialize();

  // Publish article
  const result = await publisher.publish({
    title: 'My AI-Generated Article',
    content: '# Hello World\n\nThis is my article content...',
    tags: ['AI', 'Technology'],
    publishStatus: 'draft',
    contentFormat: 'markdown',
  });

  console.log(`Published: ${result.url}`);

  await publisher.cleanup();
}

main();

AI Agent Integration

import { MediumPublisher } from '@neko-arc/medium-publisher';

async function publishAIContent(content: string) {
  const publisher = new MediumPublisher({
    accessToken: process.env.MEDIUM_ACCESS_TOKEN!,
    enableMongoLogging: true,
  });

  await publisher.initialize();

  const result = await publisher.publish({
    title: "AI-Generated Insights on Modern Tech",
    content: content,
    tags: ["AI", "Technology", "Automation"],
    publishStatus: "draft",
  }, 'ai-agent', 'my-ai-agent');

  console.log(`AI article published: ${result.url}`);
  await publisher.cleanup();
}

πŸ“Š MongoDB Schema

When MongoDB logging is enabled, publications are stored with this schema:

{
  mediumPostId: string;        // Medium post ID
  title: string;               // Article title
  url: string;                 // Medium URL
  publishStatus: string;       // 'public' | 'draft' | 'unlisted'
  tags: string[];              // Article tags
  publishedAt: Date;           // Publication timestamp
  generatedBy: string;         // Who/what created it
  source: string;              // 'manual' | 'ai-agent' | 'automated'
  contentFormat: string;       // 'markdown' | 'html'
  metadata: {
    canonicalUrl?: string;     // Canonical URL
    license?: string;          // License type
  };
  createdAt: Date;             // Record creation timestamp
}

Query Examples

// Get all drafts
db.getCollection('medium-publications').find({ publishStatus: 'draft' })

// Get AI-generated articles
db.getCollection('medium-publications').find({ source: 'ai-agent' })

// Recent publications
db.getCollection('medium-publications').find().sort({ createdAt: -1 }).limit(10)

🎯 Examples

Publish Draft Article

neko-medium publish \
  --file ./articles/tutorial.md \
  --title "Building TypeScript APIs" \
  --status draft \
  --tags "TypeScript,API,Tutorial"

Publish with Canonical URL

neko-medium publish \
  --file ./articles/crosspost.md \
  --title "Cross-Posted Article" \
  --status public \
  --canonical "https://myblog.com/original-post"

HTML Content

neko-medium publish \
  --file ./articles/page.html \
  --title "HTML Article" \
  --format html \
  --status unlisted

AI Agent Publishing

neko-medium publish \
  --file ./ai-generated.md \
  --title "AI Insights" \
  --status draft \
  --source ai-agent \
  --generated-by claude-ai

πŸ”§ API Reference

MediumPublisher Class

Constructor

new MediumPublisher(config: MediumPublisherConfig)

Config Options:

  • accessToken: string - Medium integration token (required)
  • mongoUri?: string - MongoDB connection URI
  • mongoDatabase?: string - Database name (default: 'neko-defense-system')
  • mongoCollection?: string - Collection name (default: 'medium-publications')
  • enableMongoLogging?: boolean - Enable MongoDB logging (default: false)

Methods

initialize(): Promise<void> Connect to MongoDB (if enabled). Call before publishing.

getUser(): Promise<MediumUser> Get authenticated Medium user information.

publish(article: Article, source?, generatedBy?): Promise<PublishResult> Publish article to Medium.

getPublications(): Promise<PublicationRecord[]> Get all publications from MongoDB.

getPublicationsByStatus(status): Promise<PublicationRecord[]> Get publications filtered by status.

cleanup(): Promise<void> Disconnect from MongoDB. Call after publishing.


⚠️ Important Notes

  1. Medium API Status: The Medium API is officially deprecated but still functional
  2. Draft First: Always publish as draft first for review
  3. Rate Limits: Be mindful of Medium's API rate limits
  4. No Editing: Medium API doesn't support editing published posts
  5. Private Credentials: NEVER commit .env file to git

πŸ”— Useful Links

  • Medium API Docs: https://github.com/Medium/medium-api-docs
  • Get Integration Token: https://medium.com/me/settings/security
  • MongoDB Atlas: https://cloud.mongodb.com/

πŸ“ License

MIT License


🐾 Credits

Created with love by the Neko-Arc System Nyaa~! Happy publishing, desu~! ✨

Version: 1.0.0 Last Updated: November 2025


πŸ’‘ Support

For issues or questions:

  1. Check the .env.example file for configuration
  2. Test connection with neko-medium test
  3. Verify Medium token at https://medium.com/me/settings/security
  4. Ensure MongoDB connection string is correct (if using logging)
  5. Open an issue on GitHub

πŸš€ Changelog

1.0.0 (2025-11-09)

  • Initial NPM release
  • TypeScript support
  • CLI interface
  • MongoDB logging
  • Full Medium API integration
  • AI agent ready

Part of the Neko-Arc System 🐾