Skip to content

Commit b416f5f

Browse files
committed
[Optimizing] Adding auto refresh token when expiring
1 parent 46fb29f commit b416f5f

File tree

4 files changed

+97
-68
lines changed

4 files changed

+97
-68
lines changed

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ AI‑powered YouTube uploader—no CLI, no YouTube Studio, and no secrets ever s
1212
- Multi Channel Support
1313

1414
## Demo
15-
15+
### Setup and Demo Video
1616
<p align="center"> <a href="https://youtu.be/fcywz5FIUpM" target="_blank"><img src="https://img.youtube.com/vi/fcywz5FIUpM/0.jpg"/></a> </p>
1717

1818
![output](https://github.com/user-attachments/assets/f8c2c303-ef77-4fa9-99a6-5de7f120ffac)
1919

20-
2120
## Getting Started
2221

2322
Visit the [Releases](https://github.com/anwerj/youtube-uploader-mcp/releases) page and download the appropriate binary for your operating system:
@@ -59,7 +58,6 @@ To upload to YouTube, you must configure OAuth and get a client_secret.json file
5958
### Usage
6059

6160
- `main.go`: Entry point for the CLI
62-
- `main/`: Additional main package files
6361
- `youtube/`: YouTube API integration (OAuth, video upload, config)
6462
- `tool/`: Command-line tools for authentication, token, and upload
6563
- `hook/`, `logn/`: Supporting packages

manifest.json

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"dxt_version": "0.1",
3+
"name": "youtube-uploader-mcp",
4+
"display_name": "Youtube Uploader MCP",
5+
"version": "0.1.0",
6+
"description": "AI‑powered YouTube uploader—no CLI, no YouTube Studio, and no secrets ever shared with LLMs or third‑party apps and all free of cost! It includes OAuth2 authentication, token management, and video upload functionality.",
7+
"author": {
8+
"name": "Anwerj",
9+
"email": "[email protected]",
10+
"url": "i.anwerj.com"
11+
},
12+
"documentation": "https://github.com/anwerj/youtube-uploader-mcp",
13+
"icon": "icon.png",
14+
"screenshots": [
15+
"screenshot.png"
16+
],
17+
"server": {
18+
"type": "binary",
19+
"entry_point": "server/youtube-uploader-mcp",
20+
"mcp_config": {
21+
"command": "${__dirname}/server/youtube-uploader-mcp",
22+
"args": [],
23+
"env": {}
24+
}
25+
},
26+
"tools": [
27+
{
28+
"name": "Upload Video",
29+
"description": "Uploads Video to Youtube"
30+
}
31+
],
32+
"compatibility": {
33+
"platforms": [
34+
"darwin",
35+
"win32",
36+
"linux"
37+
]
38+
},
39+
"user_config": {
40+
"client-sercret-file": {
41+
"type": "string",
42+
"title": "Client Secret File",
43+
"description": "File path to client secrets",
44+
"required": true,
45+
"sensitive": false
46+
}
47+
},
48+
"keywords": [
49+
"Youtube",
50+
"Upload",
51+
"MCP",
52+
"Youtube Server"
53+
],
54+
"license": "MIT",
55+
"repository": {
56+
"type": "git",
57+
"url": "https://github.com/anwerj/youtube-uploader-mcp"
58+
}
59+
}

tool/uploadvideo/upload_video.go

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"strings"
7+
"time"
78

89
"github.com/anwerj/youtube-uploader-mcp/tool"
910
"github.com/anwerj/youtube-uploader-mcp/youtube"
@@ -54,14 +55,19 @@ func (t *UploadVideoTool) Define(context.Context) mcp.Tool {
5455
)
5556
}
5657

57-
func (t *UploadVideoTool) Handle(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
58+
func (t *UploadVideoTool) Handle(
59+
ctx context.Context,
60+
request mcp.CallToolRequest,
61+
) (*mcp.CallToolResult, error) {
62+
5863
filePath := request.GetString("file_path", "")
5964
description := request.GetString("description", "")
6065
title := request.GetString("title", "")
6166
tags := request.GetString("tags", "")
6267
categoryID := request.GetString("category_id", "")
6368
if filePath == "" || description == "" || title == "" || tags == "" || categoryID == "" {
64-
return mcp.NewToolResultError("all fields are required: file_path, description, title, tags, category_id"), nil
69+
return mcp.NewToolResultError(
70+
"all fields are required: file_path, description, title, tags, category_id"), nil
6571
}
6672
channelId := request.GetString("channel_id", "")
6773
if channelId == "" {
@@ -75,6 +81,35 @@ func (t *UploadVideoTool) Handle(ctx context.Context, request mcp.CallToolReques
7581
return mcp.NewToolResultError("Failed to load token: " + err.Error()), nil
7682
}
7783

84+
if channel == nil ||
85+
channel.Token == nil {
86+
return mcp.NewToolResultError("channel or token is nil, please authenticate first"), nil
87+
}
88+
89+
if channel.Token.Expiry.IsZero() ||
90+
channel.Token.AccessToken == "" ||
91+
channel.Token.RefreshToken == "" {
92+
return mcp.NewToolResultError(
93+
"channel token is expired or malformed, please start authenticate"), nil
94+
}
95+
96+
// Check if token is expiring (within 2 minutes)
97+
now := time.Now().In(channel.Token.Expiry.Location())
98+
if channel.Token.Expiry.Before(now.Add(2 * time.Minute)) {
99+
newToken, err := youtube.RefreshAccessToken(channel.Token)
100+
if err != nil {
101+
return mcp.NewToolResultError(
102+
"token was expiring, Failed to refresh token: " + err.Error()), nil
103+
}
104+
channel.Token = newToken
105+
// Optionally save the refreshed token for future use
106+
err = youtube.SaveChannel(channel)
107+
if err != nil {
108+
return mcp.NewToolResultError(
109+
"token was expiring, Failed to save refreshed token: " + err.Error()), nil
110+
}
111+
}
112+
78113
video := &youtube.Video{
79114
Path: filePath,
80115
Title: title,

youtube/token.go

Lines changed: 0 additions & 63 deletions
This file was deleted.

0 commit comments

Comments
 (0)