mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-05 13:52:40 +02:00
replace broken native Jira/Linear tools with MCP equivalents
This commit is contained in:
parent
f2d9e67ac2
commit
9452d1090a
2 changed files with 143 additions and 81 deletions
|
|
@ -38,8 +38,66 @@ CRITICAL RULE — KNOWLEDGE BASE FIRST, NEVER DEFAULT TO GENERAL KNOWLEDGE:
|
|||
* Formatting, summarization, or analysis of content already present in the conversation
|
||||
* Following user instructions that are clearly task-oriented (e.g., "rewrite this in bullet points")
|
||||
* Tool-usage actions like generating reports, podcasts, images, or scraping webpages
|
||||
* Queries about services that have direct tools (Linear, ClickUp, Jira, Slack, Airtable) — see <tool_routing> below
|
||||
</knowledge_base_only_policy>
|
||||
|
||||
<tool_routing>
|
||||
CRITICAL — You have direct tools for these services: Linear, ClickUp, Jira, Slack, Airtable.
|
||||
Their data is NEVER in the knowledge base. You MUST call their tools immediately — never
|
||||
say "I don't see it in the knowledge base" or ask the user if they want you to check.
|
||||
Ignore any knowledge base results for these services.
|
||||
|
||||
When to use which tool:
|
||||
- Linear (issues) → list_issues, get_issue, save_issue (create/update)
|
||||
- ClickUp (tasks) → clickup_search, clickup_get_task
|
||||
- Jira (issues) → getAccessibleAtlassianResources (cloudId discovery), getVisibleJiraProjects (project discovery), getJiraProjectIssueTypesMetadata (issue type discovery), searchJiraIssuesUsingJql, createJiraIssue, editJiraIssue
|
||||
- Slack (messages, channels) → slack_search_channels, slack_read_channel, slack_read_thread
|
||||
- Airtable (bases, tables, records) → list_bases, list_tables_for_base, list_records_for_table
|
||||
- Knowledge base content (Notion, GitHub, files, notes) → automatically searched
|
||||
- Real-time public web data → call web_search
|
||||
- Reading a specific webpage → call scrape_webpage
|
||||
</tool_routing>
|
||||
|
||||
<parameter_resolution>
|
||||
Some service tools require identifiers or context you do not have (account IDs,
|
||||
workspace names, channel IDs, project keys, etc.). NEVER ask the user for raw
|
||||
IDs or technical identifiers — they cannot memorise them.
|
||||
|
||||
Instead, follow this discovery pattern:
|
||||
1. Call a listing/discovery tool to find available options.
|
||||
2. ONE result → use it silently, no question to the user.
|
||||
3. MULTIPLE results → present the options by their display names and let the
|
||||
user choose. Never show raw UUIDs — always use friendly names.
|
||||
|
||||
Discovery tools by level:
|
||||
- Which account/workspace? → get_connected_accounts("<service>")
|
||||
- Which Jira site (cloudId)? → getAccessibleAtlassianResources
|
||||
- Which Jira project? → getVisibleJiraProjects (after resolving cloudId)
|
||||
- Which Jira issue type? → getJiraProjectIssueTypesMetadata (after resolving project)
|
||||
- Which channel? → slack_search_channels
|
||||
- Which base? → list_bases
|
||||
- Which table? → list_tables_for_base (after resolving baseId)
|
||||
- Which task? → clickup_search
|
||||
- Which issue? → list_issues (Linear) or searchJiraIssuesUsingJql (Jira)
|
||||
|
||||
For Jira specifically: ALWAYS call getAccessibleAtlassianResources first to
|
||||
obtain the cloudId, then pass it to other Jira tools. When creating an issue,
|
||||
chain: getAccessibleAtlassianResources → getVisibleJiraProjects → createJiraIssue.
|
||||
If there is only one option at each step, use it silently. If multiple, present
|
||||
friendly names.
|
||||
|
||||
Chain discovery when needed — e.g. for Airtable records: list_bases → pick
|
||||
base → list_tables_for_base → pick table → list_records_for_table.
|
||||
|
||||
MULTI-ACCOUNT TOOL NAMING: When the user has multiple accounts connected for
|
||||
the same service, tool names are prefixed to avoid collisions — e.g.
|
||||
linear_25_list_issues and linear_30_list_issues instead of two list_issues.
|
||||
Each prefixed tool's description starts with [Account: <display_name>] so you
|
||||
know which account it targets. Use get_connected_accounts("<service>") to see
|
||||
the full list of accounts with their connector IDs and display names.
|
||||
When only one account is connected, tools have their normal unprefixed names.
|
||||
</parameter_resolution>
|
||||
|
||||
<memory_protocol>
|
||||
IMPORTANT — After understanding each user message, ALWAYS check: does this message
|
||||
reveal durable facts about the user (role, interests, preferences, projects,
|
||||
|
|
@ -76,8 +134,66 @@ CRITICAL RULE — KNOWLEDGE BASE FIRST, NEVER DEFAULT TO GENERAL KNOWLEDGE:
|
|||
* Formatting, summarization, or analysis of content already present in the conversation
|
||||
* Following user instructions that are clearly task-oriented (e.g., "rewrite this in bullet points")
|
||||
* Tool-usage actions like generating reports, podcasts, images, or scraping webpages
|
||||
* Queries about services that have direct tools (Linear, ClickUp, Jira, Slack, Airtable) — see <tool_routing> below
|
||||
</knowledge_base_only_policy>
|
||||
|
||||
<tool_routing>
|
||||
CRITICAL — You have direct tools for these services: Linear, ClickUp, Jira, Slack, Airtable.
|
||||
Their data is NEVER in the knowledge base. You MUST call their tools immediately — never
|
||||
say "I don't see it in the knowledge base" or ask if they want you to check.
|
||||
Ignore any knowledge base results for these services.
|
||||
|
||||
When to use which tool:
|
||||
- Linear (issues) → list_issues, get_issue, save_issue (create/update)
|
||||
- ClickUp (tasks) → clickup_search, clickup_get_task
|
||||
- Jira (issues) → getAccessibleAtlassianResources (cloudId discovery), getVisibleJiraProjects (project discovery), getJiraProjectIssueTypesMetadata (issue type discovery), searchJiraIssuesUsingJql, createJiraIssue, editJiraIssue
|
||||
- Slack (messages, channels) → slack_search_channels, slack_read_channel, slack_read_thread
|
||||
- Airtable (bases, tables, records) → list_bases, list_tables_for_base, list_records_for_table
|
||||
- Knowledge base content (Notion, GitHub, files, notes) → automatically searched
|
||||
- Real-time public web data → call web_search
|
||||
- Reading a specific webpage → call scrape_webpage
|
||||
</tool_routing>
|
||||
|
||||
<parameter_resolution>
|
||||
Some service tools require identifiers or context you do not have (account IDs,
|
||||
workspace names, channel IDs, project keys, etc.). NEVER ask the user for raw
|
||||
IDs or technical identifiers — they cannot memorise them.
|
||||
|
||||
Instead, follow this discovery pattern:
|
||||
1. Call a listing/discovery tool to find available options.
|
||||
2. ONE result → use it silently, no question to the user.
|
||||
3. MULTIPLE results → present the options by their display names and let the
|
||||
user choose. Never show raw UUIDs — always use friendly names.
|
||||
|
||||
Discovery tools by level:
|
||||
- Which account/workspace? → get_connected_accounts("<service>")
|
||||
- Which Jira site (cloudId)? → getAccessibleAtlassianResources
|
||||
- Which Jira project? → getVisibleJiraProjects (after resolving cloudId)
|
||||
- Which Jira issue type? → getJiraProjectIssueTypesMetadata (after resolving project)
|
||||
- Which channel? → slack_search_channels
|
||||
- Which base? → list_bases
|
||||
- Which table? → list_tables_for_base (after resolving baseId)
|
||||
- Which task? → clickup_search
|
||||
- Which issue? → list_issues (Linear) or searchJiraIssuesUsingJql (Jira)
|
||||
|
||||
For Jira specifically: ALWAYS call getAccessibleAtlassianResources first to
|
||||
obtain the cloudId, then pass it to other Jira tools. When creating an issue,
|
||||
chain: getAccessibleAtlassianResources → getVisibleJiraProjects → createJiraIssue.
|
||||
If there is only one option at each step, use it silently. If multiple, present
|
||||
friendly names.
|
||||
|
||||
Chain discovery when needed — e.g. for Airtable records: list_bases → pick
|
||||
base → list_tables_for_base → pick table → list_records_for_table.
|
||||
|
||||
MULTI-ACCOUNT TOOL NAMING: When the user has multiple accounts connected for
|
||||
the same service, tool names are prefixed to avoid collisions — e.g.
|
||||
linear_25_list_issues and linear_30_list_issues instead of two list_issues.
|
||||
Each prefixed tool's description starts with [Account: <display_name>] so you
|
||||
know which account it targets. Use get_connected_accounts("<service>") to see
|
||||
the full list of accounts with their connector IDs and display names.
|
||||
When only one account is connected, tools have their normal unprefixed names.
|
||||
</parameter_resolution>
|
||||
|
||||
<memory_protocol>
|
||||
IMPORTANT — After understanding each user message, ALWAYS check: does this message
|
||||
reveal durable facts about the team (decisions, conventions, architecture, processes,
|
||||
|
|
|
|||
|
|
@ -78,16 +78,11 @@ from .google_drive import (
|
|||
create_create_google_drive_file_tool,
|
||||
create_delete_google_drive_file_tool,
|
||||
)
|
||||
from .jira import (
|
||||
create_create_jira_issue_tool,
|
||||
create_delete_jira_issue_tool,
|
||||
create_update_jira_issue_tool,
|
||||
)
|
||||
from .linear import (
|
||||
create_create_linear_issue_tool,
|
||||
create_delete_linear_issue_tool,
|
||||
create_update_linear_issue_tool,
|
||||
)
|
||||
# NOTE: Native Jira CRUD tools (create/update/delete_jira_issue) have been
|
||||
# replaced by MCP equivalents (createJiraIssue, editJiraIssue). The native
|
||||
# tools used the REST API which is incompatible with MCP-scoped OAuth tokens.
|
||||
from .connected_accounts import create_get_connected_accounts_tool
|
||||
# NOTE: Native Linear delete tool disabled — see comment in BUILTIN_TOOLS.
|
||||
from .luma import (
|
||||
create_create_luma_event_tool,
|
||||
create_list_luma_events_tool,
|
||||
|
|
@ -242,6 +237,21 @@ BUILTIN_TOOLS: list[ToolDefinition] = [
|
|||
requires=["db_session"],
|
||||
),
|
||||
# =========================================================================
|
||||
# SERVICE ACCOUNT DISCOVERY
|
||||
# Generic tool for the LLM to discover connected accounts and resolve
|
||||
# service-specific identifiers (e.g. Jira cloudId, Slack team, etc.)
|
||||
# =========================================================================
|
||||
ToolDefinition(
|
||||
name="get_connected_accounts",
|
||||
description="Discover connected accounts for a service and their metadata",
|
||||
factory=lambda deps: create_get_connected_accounts_tool(
|
||||
db_session=deps["db_session"],
|
||||
search_space_id=deps["search_space_id"],
|
||||
user_id=deps["user_id"],
|
||||
),
|
||||
requires=["db_session", "search_space_id", "user_id"],
|
||||
),
|
||||
# =========================================================================
|
||||
# MEMORY TOOL - single update_memory, private or team by thread_visibility
|
||||
# =========================================================================
|
||||
ToolDefinition(
|
||||
|
|
@ -269,42 +279,11 @@ BUILTIN_TOOLS: list[ToolDefinition] = [
|
|||
],
|
||||
),
|
||||
# =========================================================================
|
||||
# LINEAR TOOLS - create, update, delete issues
|
||||
# Auto-disabled when no Linear connector is configured (see chat_deepagent.py)
|
||||
# LINEAR TOOLS — create/update handled by MCP save_issue. Delete/archive
|
||||
# is NOT available: the official Linear MCP server does not expose a
|
||||
# delete tool, and the native tool's GraphQL API call fails with
|
||||
# MCP-scoped tokens (401). Re-enable when Linear adds MCP delete support.
|
||||
# =========================================================================
|
||||
ToolDefinition(
|
||||
name="create_linear_issue",
|
||||
description="Create a new issue in the user's Linear workspace",
|
||||
factory=lambda deps: create_create_linear_issue_tool(
|
||||
db_session=deps["db_session"],
|
||||
search_space_id=deps["search_space_id"],
|
||||
user_id=deps["user_id"],
|
||||
),
|
||||
requires=["db_session", "search_space_id", "user_id"],
|
||||
required_connector="LINEAR_CONNECTOR",
|
||||
),
|
||||
ToolDefinition(
|
||||
name="update_linear_issue",
|
||||
description="Update an existing indexed Linear issue",
|
||||
factory=lambda deps: create_update_linear_issue_tool(
|
||||
db_session=deps["db_session"],
|
||||
search_space_id=deps["search_space_id"],
|
||||
user_id=deps["user_id"],
|
||||
),
|
||||
requires=["db_session", "search_space_id", "user_id"],
|
||||
required_connector="LINEAR_CONNECTOR",
|
||||
),
|
||||
ToolDefinition(
|
||||
name="delete_linear_issue",
|
||||
description="Archive (delete) an existing indexed Linear issue",
|
||||
factory=lambda deps: create_delete_linear_issue_tool(
|
||||
db_session=deps["db_session"],
|
||||
search_space_id=deps["search_space_id"],
|
||||
user_id=deps["user_id"],
|
||||
),
|
||||
requires=["db_session", "search_space_id", "user_id"],
|
||||
required_connector="LINEAR_CONNECTOR",
|
||||
),
|
||||
# =========================================================================
|
||||
# NOTION TOOLS - create, update, delete pages
|
||||
# Auto-disabled when no Notion connector is configured (see chat_deepagent.py)
|
||||
|
|
@ -539,42 +518,10 @@ BUILTIN_TOOLS: list[ToolDefinition] = [
|
|||
required_connector="GOOGLE_GMAIL_CONNECTOR",
|
||||
),
|
||||
# =========================================================================
|
||||
# JIRA TOOLS - create, update, delete issues
|
||||
# Auto-disabled when no Jira connector is configured (see chat_deepagent.py)
|
||||
# JIRA TOOLS — Now fully handled by MCP (createJiraIssue, editJiraIssue,
|
||||
# searchJiraIssuesUsingJql, etc.). Native tools removed because the
|
||||
# MCP-scoped OAuth token cannot call the Jira REST API.
|
||||
# =========================================================================
|
||||
ToolDefinition(
|
||||
name="create_jira_issue",
|
||||
description="Create a new issue in the user's Jira project",
|
||||
factory=lambda deps: create_create_jira_issue_tool(
|
||||
db_session=deps["db_session"],
|
||||
search_space_id=deps["search_space_id"],
|
||||
user_id=deps["user_id"],
|
||||
),
|
||||
requires=["db_session", "search_space_id", "user_id"],
|
||||
required_connector="JIRA_CONNECTOR",
|
||||
),
|
||||
ToolDefinition(
|
||||
name="update_jira_issue",
|
||||
description="Update an existing indexed Jira issue",
|
||||
factory=lambda deps: create_update_jira_issue_tool(
|
||||
db_session=deps["db_session"],
|
||||
search_space_id=deps["search_space_id"],
|
||||
user_id=deps["user_id"],
|
||||
),
|
||||
requires=["db_session", "search_space_id", "user_id"],
|
||||
required_connector="JIRA_CONNECTOR",
|
||||
),
|
||||
ToolDefinition(
|
||||
name="delete_jira_issue",
|
||||
description="Delete an existing indexed Jira issue",
|
||||
factory=lambda deps: create_delete_jira_issue_tool(
|
||||
db_session=deps["db_session"],
|
||||
search_space_id=deps["search_space_id"],
|
||||
user_id=deps["user_id"],
|
||||
),
|
||||
requires=["db_session", "search_space_id", "user_id"],
|
||||
required_connector="JIRA_CONNECTOR",
|
||||
),
|
||||
# =========================================================================
|
||||
# CONFLUENCE TOOLS - create, update, delete pages
|
||||
# Auto-disabled when no Confluence connector is configured (see chat_deepagent.py)
|
||||
|
|
@ -902,7 +849,6 @@ async def build_tools_async(
|
|||
# Log error but don't fail - just continue without MCP tools
|
||||
logging.exception(f"Failed to load MCP tools: {e!s}")
|
||||
|
||||
# Log all tools being returned to agent
|
||||
logging.info(
|
||||
f"Total tools for agent: {len(tools)} - {[t.name for t in tools]}",
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue