Skip to content

Commit eb64900

Browse files
committed
fmt
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
1 parent 4e82227 commit eb64900

1 file changed

Lines changed: 46 additions & 30 deletions

File tree

twitter/main.go

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,35 @@ const (
2525
unansweredWindow = 24 * time.Hour
2626
)
2727

28+
var debugLogging bool
29+
2830
func init() {
2931
// Disable log output by default so it doesn't break MCP stdio (stdout is used for JSON-RPC).
3032
// Set TWITTER_DEBUG=1 or MCP_TWITTER_DEBUG=1 to enable logging for debugging.
31-
if os.Getenv("TWITTER_DEBUG") == "" && os.Getenv("MCP_TWITTER_DEBUG") == "" {
33+
debugLogging = os.Getenv("TWITTER_DEBUG") != "" || os.Getenv("MCP_TWITTER_DEBUG") != ""
34+
if !debugLogging {
3235
log.SetOutput(io.Discard)
3336
}
3437
}
3538

39+
func debugLog(v ...interface{}) {
40+
if debugLogging {
41+
log.Println(v...)
42+
}
43+
}
44+
45+
func debugLogf(format string, v ...interface{}) {
46+
if debugLogging {
47+
log.Printf(format, v...)
48+
}
49+
}
50+
3651
var (
37-
client *twitter.Client
38-
authUserID string
39-
maxTweets int
40-
hasUserCtx bool
41-
v1Client *http.Client
52+
client *twitter.Client
53+
authUserID string
54+
maxTweets int
55+
hasUserCtx bool
56+
v1Client *http.Client
4257
)
4358

4459
// bearerAuthorizer adds Bearer token to requests
@@ -111,9 +126,9 @@ type GetTrendsInput struct {
111126
}
112127

113128
type GetUserRelationshipsInput struct {
114-
UserID string `json:"user_id" jsonschema:"user ID"`
115-
Type string `json:"type" jsonschema:"followers or following"`
116-
MaxResults int `json:"max_results,omitempty" jsonschema:"max users (default 50, cap 100)"`
129+
UserID string `json:"user_id" jsonschema:"user ID"`
130+
Type string `json:"type" jsonschema:"followers or following"`
131+
MaxResults int `json:"max_results,omitempty" jsonschema:"max users (default 50, cap 100)"`
117132
}
118133

119134
type FollowUserInput struct {
@@ -128,12 +143,12 @@ type UploadMediaInput struct {
128143

129144
// Simplified output types (JSON-friendly)
130145
type TweetOut struct {
131-
ID string `json:"id"`
132-
Text string `json:"text"`
133-
AuthorID string `json:"author_id,omitempty"`
134-
CreatedAt string `json:"created_at,omitempty"`
135-
Metrics map[string]int `json:"public_metrics,omitempty"`
136-
MediaURLs []string `json:"media_urls,omitempty"`
146+
ID string `json:"id"`
147+
Text string `json:"text"`
148+
AuthorID string `json:"author_id,omitempty"`
149+
CreatedAt string `json:"created_at,omitempty"`
150+
Metrics map[string]int `json:"public_metrics,omitempty"`
151+
MediaURLs []string `json:"media_urls,omitempty"`
137152
}
138153

139154
type UserOut struct {
@@ -170,9 +185,9 @@ type GetListTweetsOutput struct {
170185
}
171186

172187
type TrendOut struct {
173-
Name string `json:"name"`
174-
Query string `json:"query"`
175-
TweetVolume int `json:"tweet_volume,omitempty"`
188+
Name string `json:"name"`
189+
Query string `json:"query"`
190+
TweetVolume int `json:"tweet_volume,omitempty"`
176191
}
177192

178193
type GetTrendsOutput struct {
@@ -223,10 +238,10 @@ func tweetFromObj(t *twitter.TweetObj, includes *twitter.TweetRawIncludes) Tweet
223238
}
224239
if t.PublicMetrics != nil {
225240
out.Metrics = map[string]int{
226-
"like_count": t.PublicMetrics.Likes,
227-
"reply_count": t.PublicMetrics.Replies,
228-
"retweet_count": t.PublicMetrics.Retweets,
229-
"quote_count": t.PublicMetrics.Quotes,
241+
"like_count": t.PublicMetrics.Likes,
242+
"reply_count": t.PublicMetrics.Replies,
243+
"retweet_count": t.PublicMetrics.Retweets,
244+
"quote_count": t.PublicMetrics.Quotes,
230245
"impression_count": t.PublicMetrics.Impressions,
231246
}
232247
}
@@ -245,11 +260,11 @@ func userFromObj(u *twitter.UserObj) UserOut {
245260
return UserOut{}
246261
}
247262
out := UserOut{
248-
ID: u.ID,
249-
Name: u.Name,
250-
Username: u.UserName,
251-
Description: u.Description,
252-
ProfileImageURL: u.ProfileImageURL,
263+
ID: u.ID,
264+
Name: u.Name,
265+
Username: u.UserName,
266+
Description: u.Description,
267+
ProfileImageURL: u.ProfileImageURL,
253268
}
254269
if u.PublicMetrics != nil {
255270
out.PublicMetrics = map[string]int{
@@ -832,11 +847,11 @@ func InitClientFromEnv() bool {
832847
ctx := context.Background()
833848
resp, err := client.AuthUserLookup(ctx, twitter.UserLookupOpts{})
834849
if err != nil {
835-
log.Printf("Warning: could not resolve auth user: %v", err)
850+
debugLogf("Warning: could not resolve auth user: %v", err)
836851
} else if resp.Raw != nil && len(resp.Raw.Users) > 0 {
837852
authUserID = resp.Raw.Users[0].ID
838853
}
839-
log.Println("Twitter MCP: using OAuth 1.0a user context")
854+
debugLog("Twitter MCP: using OAuth 1.0a user context")
840855
return true
841856
}
842857
if bearer != "" {
@@ -845,7 +860,7 @@ func InitClientFromEnv() bool {
845860
Client: http.DefaultClient,
846861
Host: "https://api.twitter.com",
847862
}
848-
log.Println("Twitter MCP: using Bearer (app-only); write and home/mentions tools will fail without user context")
863+
debugLog("Twitter MCP: using Bearer (app-only); write and home/mentions tools will fail without user context")
849864
return true
850865
}
851866
return false
@@ -856,6 +871,7 @@ func main() {
856871
fmt.Fprintln(os.Stderr, "twitter MCP: Set TWITTER_BEARER_TOKEN or all of TWITTER_API_KEY, TWITTER_API_SECRET, TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_SECRET")
857872
os.Exit(1)
858873
}
874+
859875
server := mcp.NewServer(&mcp.Implementation{Name: "twitter", Version: "v1.0.0"}, nil)
860876
mcp.AddTool(server, &mcp.Tool{Name: "get_tweets", Description: "Fetch recent tweets from a user (with media support)"}, GetTweets)
861877
mcp.AddTool(server, &mcp.Tool{Name: "get_profile", Description: "Get a user's profile information"}, GetProfile)

0 commit comments

Comments
 (0)