Skip to main content
Glama

viruagent-mcp

viruagent의 포스팅 기능을 MCP 서버로 노출한 패키지입니다.

CLI 기반 AI Agent가 티스토리 글을 작성·업로드·발행(공개/비공개)까지 한 번에 처리하는 MCP입니다.
OpenAI Function Calling으로 의도를 정하고, MCP/Playwright/Tistory API가 실행을 분리 수행합니다.

  • AI Agent: 요청 파라미터 결정

  • MCP Tool: publish/save_draft/list_categories 호출 인터페이스

  • Playwright: 로그인·2차인증·세션, Tistory API: 발행/임시저장/카테고리/이미지 처리

최근 반영사항

  • 2026-02-27: publish에서 403 발생 시 우선 비공개 발행(visibility: 0)으로 fallback 합니다.

  • 동일 일시에서 403이 반복되면 비공개 발행도 실패하고, 해당 에러를 반환해 다시 시도/리커버리 제어할 수 있도록 구성했습니다.

Related MCP server: velog-mcp

설치

cd /Users/tk/Desktop/project/viruagent-mcp
npm install

실행

npm start

또는

node bin/index.js

제공 tool

- viruagent_auth_status
- viruagent_login
- viruagent_publish
- viruagent_save_draft
- viruagent_list_categories
- viruagent_list_posts
- viruagent_logout
- viruagent_list_providers

기본 사용 예시 (MCP 클라이언트 설정)

{
  "mcpServers": {
    "viruagent-mcp": {
      "command": "node",
      "args": ["/Users/tk/Desktop/project/viruagent-mcp/bin/index.js"]
    }
  }
}

동작 포인트

  • session 파일은 사용자 홈(~/.viruagent-mcp/sessions)에 provider별로 분리 저장됩니다.

  • viruagent_login은 기본적으로 브라우저를 띄워 티스토리 로그인 -> 카카오 로그인 페이지 이동 -> 로그인/2차 인증 흐름을 처리합니다.

  • viruagent_login은 아이디/비밀번호 자동 로그인을 지원합니다.

  • 카카오톡 푸시 2차 인증이 감지되면, 사용자 승인 대기(status: "pending_2fa") 상태를 반환하고 승인 완료 후 재시도할 수 있습니다.

  • remember browser(이 브라우저에서 2차 인증 사용 안 함)에 해당하는 체크박스가 보이면 자동 체크를 시도합니다.

  • viruagent_publish는 category가 없으면 카테고리 목록을 돌려주고 사용자가 category를 지정해 다시 요청하게 합니다. (카테고리가 하나뿐이면 자동 선택)

  • viruagent_publish는 발행 요청 시 403(발행 제한) 오류가 발생하면 visibility: 0(비공개) 발행으로 먼저 fallback를 시도합니다.

  • viruagent_publish는 본문 placeholder(<!-- IMAGE: keyword -->)를 발견하면 imageUrls를 받아 원격 URL이면 로컬로 다운로드하고, 로컬 파일 경로면 바로 업로드합니다. 업로드는 Tistory 이미지 업로드 API를 통해 진행됩니다. 성공 시 본문에는 업로드된 이미지 URL이 <img src="..."> 형태로 삽입됩니다. 썸네일은 업로드된 이미지 키(kage@...) 기준으로 자동 후보를 생성합니다.

  • viruagent_save_draft도 동일한 이미지 치환 파이프라인을 사용합니다.

  • 업로드된 첫 번째 이미지는 썸네일 자동 후보가 됩니다. (thumbnail 직접 지정이 우선)

  • thumbnailkage@... 형식이 가장 안전합니다. (thumbnail이 비어 있으면 업로드된 첫 이미지의 kage@ 키를 자동 사용)

  • relatedImageKeywords는 이미지 수집용 힌트이며, 실제 업로드는 imageUrls가 있을 때만 수행됩니다.

  • autoUploadImagesimageUploadLimitplaceholder+URL 처리 동작을 제어합니다.

자동 로그인 사용법

  1. 환경변수 설정

export TISTORY_USERNAME="your-id"
export TISTORY_PASSWORD="your-password"
  1. MCP 도구 호출 예시

{
  "name": "viruagent_login",
  "arguments": {
    "provider": "tistory",
    "headless": true,
    "username": "your-id",
    "password": "your-password"
  }
}

발행 요청 시 카테고리를 생략하면 아래처럼 status: "need_category" 응답이 올 수 있습니다.

{
  "provider": "tistory",
  "mode": "publish",
  "status": "need_category",
  "loggedIn": true,
  "title": "자동 테스트 글",
  "visibility": 0,
  "tags": "테스트",
  "message": "category가 없어서 중단했습니다. 카테고리 ID를 지정해 publish를 재요청해 주세요.",
  "categories": [
    { "name": "기본", "id": 0 }
 ]
}

이미지 업로드 단계에서 실패가 발생하면 아래 상태가 반환됩니다.

  • status: "image_upload_failed": 플레이스홀더가 있지만 업로드된 이미지가 0개

  • status: "image_upload_partial": 일부 업로드 실패

실패 응답에는 uploadErrors에 실패 URL/에러 메시지가 들어오므로, 동일 title/contentimageUrls만 보완해서 재요청하세요.

발행이 403으로 막혀 비공개로 fallback된 경우:

{
  "provider": "tistory",
  "mode": "publish",
  "status": "publish_fallback_to_private",
  "visibility": 0,
  "message": "발행 제한(403)으로 인해 비공개로 발행했습니다."
}

발행 403이 비공개 fallback에서도 반복되어 실패한 경우:

{
  "provider": "tistory",
  "mode": "publish",
  "status": "publish_fallback_to_private_failed",
  "visibility": 0,
  "message": "발행 제한(403)으로 인해 공개/비공개 모두 실패했습니다."
}

2차 인증이 있으면 twoFactorCode를 추가로 전달합니다.

  • 카카오톡 푸시 방식에서는 twoFactorCode가 없어도 자동으로 2차 인증 승인 대기 후 실패 시 pending_2fa 결과가 반환될 수 있습니다.

viruagent_publish 이미지 자동 업로드 예시:

{
  "name": "viruagent_publish",
  "arguments": {
    "provider": "tistory",
    "title": "최신 IT 뉴스 요약",
    "content": "<blockquote data-ke-style=\"style1\">...</blockquote><!-- IMAGE: galaxy s26 --><p>...</p>",
    "visibility": "public",
    "category": 1284210,
    "tags": "IT,뉴스",
    "relatedImageKeywords": ["galaxy s26", "AI phone"],
    "imageUrls": ["https://example.com/image1.jpg", "https://example.com/image2.jpg"],
    "autoUploadImages": true,
    "imageUploadLimit": 3
  }
}

pending_2fa 응답 예시:

{
  "provider": "tistory",
  "status": "pending_2fa",
  "loggedIn": false,
  "message": "카카오 2차 인증이 필요합니다. 앱에서 인증 후 다시 실행하면 됩니다."
}
  • 현재 Naver provider는 스텁이며, 요청 시 ready:false 형태로 사용 가능 여부를 반환합니다.

Available Tools

4 tools
viruagent_list_categoriesC

Provider 카테고리 목록 조회

ParametersJSON Schema
NameRequiredDescriptionDefault
providerNotistory

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, and description only says 'view category list'. Does not disclose whether the operation is read-only, if authentication is needed, or any side effects. For a list operation, it likely is safe, but this is not stated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Extremely concise: a single short phrase in Korean. No unnecessary words, but could benefit from an English translation or slight expansion for clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given low complexity (one optional parameter with enum, no output schema), the description is adequate but incomplete. Misses parameter explanation and output description, making it minimally viable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not mention the 'provider' parameter, its enum values, or default. The description adds no value beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description states 'Provider category list view', which clearly indicates the tool lists categories for providers. While it distinguishes from sibling tools (publish, read, save) by naming the resource, it could be more explicit about the action being listing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives. Does not mention prerequisites, context, or when to choose another tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

viruagent_publishB

제목/본문으로 발행을 시도하고, 403(일일 발행 제한) 발생 시 임시저장으로 폴백합니다.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagsNo쉼표 구분 태그 문자열
titleYes발행할 글 제목
contentYesHTML 포맷 본문
categoryNo카테고리 ID(숫자)
providerNotistory
imageUrlsNo클라이언트(Claude/Codex)가 수집한 이미지 경로 목록. URL(http/https) 또는 로컬 파일 경로를 허용합니다. URL은 로컬 임시 파일로 저장 후 업로드됩니다.
thumbnailNo썸네일 업로드 키 문자열(선택)
visibilityNopublic
autoUploadImagesNo웹 이미지 자동 다운로드/업로드 사용 여부
imageUploadLimitNo자동 업로드할 이미지 개수 (고정 1개)
minimumImageCountNo최소 업로드 이미지 개수 (고정 1개)
enforceSystemPromptNosystem-prompt.md 규격 위반 시 publish를 막고 위반 사유 반환
relatedImageKeywordsNo본문에 삽입할 관련 이미지 키워드(예: ["갤럭시", "AI"])

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must fully disclose behavior. It discloses the 403 fallback to draft, which is important, but does not cover other aspects like authentication, idempotency, or whether it updates existing posts. This is adequate but minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that is very concise and front-loaded with the action. It is efficient but could include more detail without being verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 13 parameters, no output schema, and no annotations, the description is too brief. It does not explain return values, error handling beyond 403, or detailed fallback behavior. More context is needed for a tool of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is high (85%), so the schema already explains most parameters. The description does not add any additional meaning to parameters beyond what is in the schema. A baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool attempts to publish a post with title/content and falls back to draft on 403 error. While it distinguishes from siblings by mentioning draft fallback, it could be more explicit about its primary purpose versus viruagent_save_draft.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for publishing with automatic draft fallback, but lacks explicit guidance on when to use this tool versus viruagent_save_draft or other siblings. The fallback behavior is mentioned but not compared to alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

viruagent_read_postB

postId로 글 본문/썸네일을 조회합니다.

ParametersJSON Schema
NameRequiredDescriptionDefault
postIdYes조회할 글 ID
providerNotistory
includeDraftNo초안 조회 플래그(현재는 tistory만 동작)

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided. Description does not disclose permissions, rate limits, side effects, or behavior for missing posts. For a read operation, safety is implied but not stated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single short sentence with no wasted words, but could benefit from slightly more detail. Efficient yet minimal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema; description does not explain return structure beyond 'content/thumbnail'. Missing details on provider and includeDraft behavior. Incomplete for a 3-param tool with no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% with descriptions for postId and includeDraft; description adds no parameter detail beyond schema. Baseline 3 applies as schema covers most.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description uses specific verb '조회' (retrieve) and resource '글 본문/썸네일' (post content/thumbnail), clearly distinguishing from sibling tools like publish or list_categories.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives (e.g., vs save_draft for drafts). The description only states the action without context for selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

viruagent_save_draftA

제목/본문으로 임시저장합니다. 이미지 플레이스홀더 치환은 publish와 동일하게 수행합니다.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagsNo태그 문자열
titleYes임시저장 제목
contentYes임시저장 본문
categoryNo카테고리 ID(미지정 시 0)
providerNotistory
imageUrlsNo임시저장 시 삽입할 이미지 URL 목록. URL(http/https) 또는 로컬 파일 경로
autoUploadImagesNo자동 이미지 업로드 사용 여부
imageUploadLimitNo자동 업로드할 이미지 개수 (고정 1개)
minimumImageCountNo최소 업로드 이미지 개수 (고정 1개)
enforceSystemPromptNosystem-prompt.md 규격 위반 시 임시저장도 막고 위반 사유 반환
relatedImageKeywordsNo본문 이미지 플레이스홀더 키워드(예: ["갤럭시", "AI"])

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It discloses that image placeholder replacement is identical to publish, which is useful behavioral info. However, it omits other important behaviors like whether drafts can be overwritten, required permissions, or output format.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise with two short sentences. No unnecessary words, every sentence provides relevant information. It is front-loaded with the core action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 11 parameters and no output schema, the description is insufficient. It does not explain the purpose of many parameters, how to use image URLs, the effect of enforceSystemPrompt, or what happens on success/failure. Significant gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is very high (91%), so baseline is 3. The description adds minimal value beyond the schema, only reiterating title/content and the image replacement behavior. It does not explain how parameters like imageUrls interact with autoUploadImages or relatedImageKeywords.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool saves a draft with title and content, and distinguishes it from 'publish' by explicitly mentioning that image placeholder replacement is performed the same as publish. The verb and resource are specific and not a tautology.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context by comparing behavior with the sibling 'publish' tool, implying that this tool is for saving drafts rather than publishing. However, it lacks explicit guidance on when not to use it or direct mention of alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

B3.4/5.0
Disambiguation5/5

Each tool has a distinct purpose: listing categories, publishing with fallback, reading posts, and saving drafts. No overlap in functionality.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern with snake_case (e.g., list_categories, read_post, save_draft), prefixed by viruagent_.

Tool Count5/5

4 tools is well-scoped for a blog publishing assistant, covering essential actions without unnecessary extras.

Completeness3/5

Missing typical CRUD operations like listing posts/drafts, updating, or deleting, which could hinder agent workflows.

Maintenance

ActivityInactive
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

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/greekr4/viruagent-mcp'

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